带有静态constexpr const char *和完美转发的链接器错误(未定义引用) [英] Linker error (undefined reference) with `static constexpr const char*` and perfect-forwarding
问题描述
#include <iostream>
using namespace std;
template<typename T> void print(T&& mX)
{
std::cout << std::forward<T>(mX) << std::endl;
}
struct SomeStruct
{
static constexpr const char* someString{"hello!"};
SomeStruct()
{
print(someString);
}
};
int main()
{
SomeStruct s{};
return 0;
}
clang++ -std=c++1y ./code.cpp -o code.o
/tmp/code-a049fe.o:在函数"SomeStruct :: SomeStruct()"中: ./code.cpp:(.text._ZN10SomeStructC2Ev[_ZN10SomeStructC2Ev]+0xa): 未定义对`SomeStruct :: someString'的引用lang:错误:链接器 命令失败,退出代码为1(使用-v查看调用)
/tmp/code-a049fe.o: In function `SomeStruct::SomeStruct()': ./code.cpp:(.text._ZN10SomeStructC2Ev[_ZN10SomeStructC2Ev]+0xa): undefined reference to `SomeStruct::someString' clang: error: linker command failed with exit code 1 (use -v to see invocation)
g++ -std=c++1y ./code.cpp -o code.o
/tmp/ccyrTsjS.o:在函数`SomeStruct :: SomeStruct()'中: code.cpp :(.text._ZN10SomeStructC2Ev [_ZN10SomeStructC5Ev] + 0xd): 未定义对`SomeStruct :: someString'的引用collect2:错误:ld 返回了1个退出状态
/tmp/ccyrTsjS.o: In function `SomeStruct::SomeStruct()': code.cpp:(.text._ZN10SomeStructC2Ev[_ZN10SomeStructC5Ev]+0xd): undefined reference to `SomeStruct::someString' collect2: error: ld returned 1 exit status
为什么发生此链接器错误? someString
是否应该在编译时即可解析?
Why is this linker error happening? Isn't someString
supposed to be resolvable at compile-time?
此外,如果将print(someString)
替换为cout << someString;
推荐答案
由于您正在引用变量,因此该变量被odr-使用,并且这需要一个异常的定义:
Because you are taking a reference the variable is odr-used and this requires a definition out of line:
constexpr const char* SomeStruct::someString;
摘自C ++ 14标准草案的3.2
[basic.def.odr] :
From the draft C++14 standard section 3.2
[basic.def.odr]:
除非应用,否则变量x的名称将显示为可能评估的表达式ex,而ex会使用它 从左值到右值(4.1)到x的转换将产生一个常量表达式(5.20),该常量表达式不会调用任何平凡的 函数,如果x是一个对象,则ex是表达式e的一组潜在结果的元素, 将左值到右值转换(4.1)应用于e或e是舍弃值表达式[...]
A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying the lvalue-to-rvalue conversion (4.1) to x yields a constant expression (5.20) that does not invoke any nontrivial functions and, if x is an object, ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion (4.1) is applied to e, or e is a discarded-value expression [...]
例如,以下替代方法print
不能odr使用someString
:
For example the following alternative print
would not odr-use someString
:
template<typename T> void print(T mX)
{
std::cout << mX << std::endl;
}
这篇关于带有静态constexpr const char *和完美转发的链接器错误(未定义引用)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!