G++ (C++14) 链接器错误,用于处理 C++03 代码
G++ (C++14) linker error on working C++03 code
请考虑以下代码段。
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;
}
编译使用 C++03 并生成输出:
-3
-3
-3
但是,使用 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
奇怪的是,这只发生在矢量b
上。如果有强制转换到双精度(a
(甚至双精度并返回int(c
(,代码将按预期运行。
如何解释这种行为?
直到 C++11std::vector::resize()
的签名是
void resize( size_type count, T value = T() );
现在它反而是
void resize( size_type count, T const& value );
从按值传递到按常量引用传递会导致调用站点使用 ODRaClass::HALLO
而以前没有。 强制转换为double
然后返回到int
会产生临时,从而避免使用 ODR;对a.resize()
的调用出于同样的原因,因为int
值被隐式强制转换为double
,并且参数引用绑定到生成的临时值。
这里通常的解决方法是为aClass::HALLO
提供一个定义;如果出于某种原因你不希望这样做,那么产生临时以避免使用ODR的简写是应用一元operator+
:
b.resize(10, +aClass::HALLO);
它适用于double
向量而不是int
的原因很有趣。std::vector::resize
的签名自 C++11 起void resize(size_type count, const value_type& value )
。对对象的引用使其被 ODR 使用,因此,现在需要在应用程序中的某个位置定义静态int
成员。
但是,当您std::vector<double>
时,不能绑定对对象的引用。相反,编译器创建一个临时double
对象,并将引用绑定到所述临时对象。因此,您可以避免使用 ODR 类的静态成员,因为创建临时double
不会 ODR 使用它,并且使用 ODR 临时就可以了。
如果您有该类.cpp文件,则解决此问题是微不足道的,在这种情况下,您只需在那里定义静态即可。但是,对于仅标头类,直到 C++17 年,解决方案都不是微不足道的,您可以在其中拥有内联变量并有一个非常好的解决方案:
#include <vector>
class aClass
{
public:
static const int HALLO;
};
inline const int aClass::HALLO = -3;
int main()
{
std::vector<int> b;
b.resize(10,aClass::HALLO); //fine
return 0;
}
- 余数运算符的等效操作,用于处理低于允许的最小值
- 用于处理多个通信协议处理的设计类
- G++ (C++14) 链接器错误,用于处理 C++03 代码
- 用于处理重新启动时剩余天数的逻辑
- (C )正在创建专门用于处理所有其他自定义对象的类/对象一种处理项目的正确方法
- 模板函数,用于处理 C++ 中的不同数组维度和数据类型
- 用于处理超出范围错误的异常类 - C++
- 用于处理索引不断变化的数组的数据结构
- C/CPP 宏或预处理器,用于处理方法的多个版本
- 重载函数,用于处理 C++11 中的多个值类
- 一个用于处理字符* 和 wchar_t* 的函数
- std::用于处理短字符串的字符串性能
- 用于处理 3 个整数列表的数据结构
- C++:用于处理整数和字符串的函数模板
- 用于处理许多客户端 c++ 的分叉服务器
- 用于处理周期性事件的开源库
- 无法从C++代码中检索正确的字符串.是否有一种通用类型用于处理c#上的无符号字符*
- 用于处理实例"数据库"的模式
- C++运算符语法,用于处理 a = b + c,而无需在 "a.data_ptr" 中显式复制数据
- 用于处理大数组的虚拟内存示例