Ric*_*rdo 2 c++ static g++ linker-errors
考虑以下代码.
class aClass
{
public:
static const int HALLO = -3;
};
int main()
{
std::vector<double > a;
std::vector<int> b;
std::vector<int> c;
int d = aClass::HALLO; //fine
a.resize(10,aClass::HALLO); //fine
b.resize(10,aClass::HALLO); // linker error c++11 and c++14
c.resize(10,(int)(double)aClass::HALLO); //fine
std::cout<<a[0]<<endl;
std::cout<<b[0]<<endl;
std::cout<<c[0]<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译与C++ 03一起使用并产生输出:
-3
-3
-3
Run Code Online (Sandbox Code Playgroud)
但是,使用C++ 11或C++ 14进行编译会导致链接器错误:
/tmp/cc3BARzY.o: In Funktion `main':
main.cpp:(.text+0x66): Nicht definierter Verweis auf `aClass::HALLO'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
奇怪的是,这只发生在矢量上b.如果有一个强制转换为double(a)或甚至是double并返回到int(c),则代码按预期运行.
如何解释这种行为?
Pre-C++ 11的签名std::vector::resize()是
void resize( size_type count, T value = T() );
Run Code Online (Sandbox Code Playgroud)
现在它反过来了
void resize( size_type count, const value_type& value );
Run Code Online (Sandbox Code Playgroud)
从pass-by-value到pass-by-const-ref的更改导致callsite 在以前没有使用的 aClass::HALLO地方使用ODR.double然后再投射回来以int避免使用ODR的方式产生临时性; 由于a.resize()同样的原因调用了作品,因为该int值被隐式地强制转换为double绑定参数之前的参数.
这里通常的解决办法是提供一个定义的aClass::HALLO; 如果出于某种原因对你不利,那么产生临时性以避免ODR使用的简写就是应用一元operator+:
b.resize(10, +aClass::HALLO);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
157 次 |
| 最近记录: |