[英]C++11 MinGW 4.9.1 shared_ptr and const static class field result “Undefined reference”
#include <memory>
class CItem
{
private:
int m_inner;
public:
static const int CAP = 1;
CItem(int temp) : m_inner(temp) {}
};
typedef std::shared_ptr<CItem> TPItem;
int main()
{
int tttt = CItem::CAP;
CItem *temp = new CItem(CItem::CAP);
TPItem temp2(temp);
TPItem temp3 = std::make_shared<CItem>(tttt);
TPItem temp4 = std::make_shared<CItem>(CItem::CAP); //On MinGW there error: "undefined reference to `CItem::CAP'"
return 0;
}
Where my fault? 我的错在哪里?
This is because CItem::CAP
is odr-used by std::make_shared
( emphasis mine ): 这是因为CItem::CAP
是ODR使用的通过std::make_shared
( 重点煤矿 ):
Informally , an object is odr-used if its address is taken, or a reference is bound to it , and a function is odr-used if a function call to it is made or its address is taken. 非正式地 , 如果使用对象的地址或将引用绑定到该对象,则该对象为odr-use, 如果对该对象进行函数调用或使用其地址,则该函数为odr-used。 If an object or a function is odr-used, its definition must exist somewhere in the program; 如果使用对象或函数,则其定义必须存在于程序中的某个位置。 a violation of that is a link-time error. 违反此规定是链接时错误。
Since std::make_shared takes its arguments by reference, this counts as an odr-use. 由于std :: make_shared通过引用接受其参数,因此算作odr使用。
which means you are required to provide an out of class definition as well: 这意味着您还需要提供类外定义:
const int CItem::CAP ;
or avoid the odr-use such as in this case: 或避免在这种情况下使用odr:
TPItem temp3 = std::make_shared<CItem>(tttt) ;
For reference the draft C++11 standard section 3.2
[basic.def.odr] says: 作为参考,C ++ 11标准草案第3.2
节[basic.def.odr]说:
An expression is potentially evaluated unless it is an unevaluated operand (Clause 5) or a subexpression thereof. 除非表达式是未评估的操作数(第5条)或其子表达式,否则可能会对其进行评估。 A variable whose name appears as a potentially-evaluated expression is odr-used unless it is an object that satisfies the requirements for appearing in a constant expression (5.19) and the lvalue-to-rvalue conversion (4.1) is immediately applied . 除非其对象满足在常量表达式中出现的要求(5.19)并且立即应用左值到右值转换(4.1) , 否则将使用其名称显示为可能评估的表达式的变量。
CItem::CAP
is a constant expression and in all the cases except this one: CItem::CAP
是一个常数表达式,在除此以外的所有情况下:
TPItem temp4 = std::make_shared<CItem>(CItem::CAP);
the lvalue-to-rvalue conversion is applied immediately. 左值到右值的转换将立即应用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.