Vit*_*meo 3 c++ linker constexpr perfect-forwarding c++14
#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;
}
Run Code Online (Sandbox Code Playgroud)
clang++ -std=c++1y ./code.cpp -o code.o
/tmp/code-a049fe.o:在函数“ SomeStruct :: SomeStruct()”中:./code.cpp:(.text._ZN10SomeStructC2Ev[_ZN10SomeStructC2Ev]+0xa):未定义对“ SomeStruct :: someString”的引用:错误:链接器命令失败,退出代码为1(使用-v查看调用)
g++ -std=c++1y ./code.cpp -o code.o
/tmp/ccyrTsjS.o:在函数“ SomeStruct :: SomeStruct()”中:code.cpp :(。text._ZN10SomeStructC2Ev [_ZN10SomeStructC5Ev] + 0xd):未定义对“ SomeStruct :: someString”的引用collect2:错误:trud退出状态
为什么发生此链接器错误?难道someString在编译时就无法解决吗?
另外,如果print(someString)将其替换为错误,则不会发生cout << someString;
因为您正在引用,所以该变量是odd-used,并且这需要一个异常定义:
constexpr const char* SomeStruct::someString;
Run Code Online (Sandbox Code Playgroud)
在C ++ 14标准草案3.2 [basic.def.odr]中:
变量x的名称显示为可能值表达式ex,否则ex会使用它,除非对x进行左值到右值转换(4.1)会产生不调用任何平凡函数的常量表达式(5.20),如果x是对象,ex是表达式e的一组潜在结果的元素,其中,将左值到右值转换(4.1)应用于e,或者e是舍弃值表达式[...]
例如,以下替代方法print将不能odr-use someString:
template<typename T> void print(T mX)
{
std::cout << mX << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2328 次 |
| 最近记录: |