gpt4 book ai didi

c++ - 对外部模板 constexpr 构造函数的 undefined reference

转载 作者:太空狗 更新时间:2023-10-29 22:54:11 26 4
gpt4 key购买 nike

这是我可以生成的显示此行为的最小示例:

foo.h

#pragma once

#include <string>

template <int I>
struct foo
{
constexpr explicit foo(int k)
: j(k + I)
{ }

std::string to_string() const;

private:

int j;
};

extern template struct foo<0>;

constexpr foo<0> operator"" _foo0(unsigned long long int v)
{
return foo<0>(static_cast<int>(v));
}

foo.cpp

#include "foo.h"

template <int I>
std::string foo<I>::to_string() const
{
return std::to_string(j);
}

template struct foo<0>;

bar.h

#pragma once

#include "foo.h"
#include <vector>

template <typename T>
struct bar
{
explicit bar(int i);

private:

std::vector<T> vec;
};

extern template struct bar<foo<0>>;

bar.cpp

#include "bar.h"

template <typename T>
bar<T>::bar(int i)
{
vec.push_back(T{i});
}

template struct bar<foo<0>>;

用法如下:

main.cpp

#include "bar.h"

int main()
{
bar<foo<0>> b2(5);
}

在 GCC 下编译它(我已经尝试了 7.4.0 和 8.3.0):

g++-8 foo.cpp bar.cpp main.cpp -std=c++14 -Wall -Werror -o test

给出错误:

bar.cpp:(.text._ZN3barI3fooILi0EEEC2Ei[_ZN3barI3fooILi0EEEC5Ei]+0x3c): undefined reference to `foo<0>::foo(int)'

Clang 版本 4 到 7 似乎接受这一点。

两个小改动让 GCC 接受它:

  1. 删除 constexpr operator"" 定义,或者
  2. operator""foo 构造函数更改为 inline 而不是 constexpr

这是否合法,GCC 是否有正当理由拒绝它?

最佳答案

我对你的资源进行了很多尝试并得到了以下结果:

gcc9.1.0 编译没有问题!

现在对 gcc 8.3.0 感到好奇:

g++ main.cpp foo.cpp bar.cpp -std=c++14 -Wall // fails: undef reference

正如您所说的那样失败了!

但没有 -Wall 它编译!

g++ main.cpp foo.cpp bar.cpp -std=c++14  // compiles, no linker error!

还有

g++ main.cpp foo.cpp bar.cpp -std=c++17 -Wall // compiles, no linker error!

我不知道为什么标志 -Wall 与生成的中间文件有任何关系。 -Wall 不应该影响任何生成的代码,因为它只是一种诊断。所以对我来说这只是一个 gcc 错误!所以请填写错误报告!

关于c++ - 对外部模板 constexpr 构造函数的 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56963557/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com