带有静态constexpr const char *和完美转发的链接器错误(未定义引用) [英] Linker error (undefined reference) with `static constexpr const char*` and perfect-forwarding

查看:520
本文介绍了带有静态constexpr const char *和完美转发的链接器错误(未定义引用)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆