链接器错误(未定义的引用)与“static constexpr const char*”和完美转发[重复]

2023-12-30

#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' 的未定义引用 clang:错误:链接器 命令失败,退出代码为 1(使用 -v 查看调用)


g++ -std=c++1y ./code.cpp -o code.o

/tmp/ccyrTsjS.o:在函数 `SomeStruct::SomeStruct()' 中: 代码.cpp:(.text._ZN10SomeStructC2Ev[_ZN10SomeStructC5Ev]+0xd): 对“SomeStruct::someString”collect2 的未定义引用:错误:ld 返回 1 退出状态


为什么会发生这个链接器错误?不是someString应该可以在编译时解析吗?

另外,如果满足以下条件,则不会发生错误print(someString)被替换为cout << someString;


因为您正在获取引用,所以该变量是 odr 使用的,这需要一个超出范围的定义:

constexpr const char* SomeStruct::someString;

看到它实时运行 http://coliru.stacked-crooked.com/a/ecd786eb2f72b231.

来自 C++14 标准草案部分3.2 [基本.def.odr]:

名称显示为潜在求值表达式 ex 的变量 x 被 ex odr 使用,除非应用 x 的左值到右值转换(4.1)产生一个常量表达式(5.20),它不会调用任何非平凡的 函数,如果 x 是对象,则 ex 是表达式 e 的潜在结果集合的元素, 其中左值到右值转换 (4.1) 应用于 e,或者 e 是丢弃值表达式 [...]

例如以下替代方案print不会使用 ODRsomeString:

template<typename T> void print(T mX) 
{
    std::cout << mX << std::endl;  
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

链接器错误(未定义的引用)与“static constexpr const char*”和完美转发[重复] 的相关文章

随机推荐