c++ - 链接器错误( undefined reference )与 `static constexpr const char*` 和完美转发

标签 c++ linker c++14 constexpr 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: 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: In function `SomeStruct::SomeStruct()': code.cpp:(.text._ZN10SomeStructC2Ev[_ZN10SomeStructC5Ev]+0xd): undefined reference to `SomeStruct::someString' collect2: error: ld returned 1 exit status


为什么会出现此链接器错误?不是 someString应该在编译时可解析?

此外,如果 print(someString) 则不会发生错误替换为 cout << someString;

最佳答案

因为你正在引用变量是 odr-used 并且这需要一个不符合规则的定义:

constexpr const char* SomeStruct::someString;

see it working live .

来自 C++14 标准草案 3.2 [basic.def.odr]:

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-use someString:

template<typename T> void print(T mX) 
{
    std::cout << mX << std::endl;  
}

关于c++ - 链接器错误( undefined reference )与 `static constexpr const char*` 和完美转发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28839672/

相关文章:

dll - 在Windows中静态链接DLL

c++ - 使用不包括基类的模板从 C++ 列表中查找特定类型

c++ - 为什么这个变量在 C++14 中的 g++ 中没有被推断为 initializer_list?

C++ 链接器找不到函数声明( undefined reference )

linux - 是否可以在不访问库本身的情况下链接到共享库?

c++11 - std::move-如何警告程序员不要使用* move 自*对象

c++ - 等价于std::vector和其他形式的两种形式的初始化列表

c++ - 如何确保类的每个数据成员都已在其复制构造函数中复制?

c++ - 从未加权图中打印最短路径

c++ - 使用wininet的异步请求