c++ - constexpr : literal class type copy behavior

标签 c++ c++11 static-members constexpr

让我们看下面的代码:

class   const_int                                                                                                                                                                                                    
{                                                                                                                                                                                                                    
public:                                                                                                                                                                                                              
  constexpr const_int(int data) : data_(data) {}                                                                                                                                                                     
  constexpr const_int(const const_int &) = default;                                                                                                                                                                  
  constexpr const_int(const_int &&) = default;                                                                                                                                                                       

private:                                                                                                                                                                                                             
  int   data_;                                                                                                                                                                                                       
};

class   test                                                                                                                                                                                                         
{                                                                                                                                                                                                                    
public:                                                                                                                                                                                                              

  constexpr static const const_int      USER = 42;                                                                                                                                                                

  constexpr static const double         NATIVE = 4.2;                                                                                                                                                                
};

// constexpr const const_int test::USER;

void    pass_by_copie(double)                                                                                                                                                                                        
{                                                                                                                                                                                                                    
}

void    pass_by_copie(const_int)                                                                                                                                                                                     
{                                                                                                                                                                                                                    
}

void    pass_by_const_ref(const const_int&)                                                                                                                                                                          
{                                                                                                                                                                                                                    
}

void    pass_by_rvalue_ref(const_int&&)                                                                                                                                                                              
{                                                                                                                                                                                                                    
}

int     main(void)                                                                                                                                                                                                   
{                                                                                                                                                                                                                    

  pass_by_copie(test::NATIVE);                                                                                                                                                                                       

  pass_by_copie(test::USER);                                                                                                                                                                                         

  pass_by_const_ref(test::USER);                                                                                                                                                                                         

  pass_by_rvalue_ref(const_int(test::USER));                                                                                                                                                                         

  return (0);                                                                                                                                                                                                        
}

以下两行:

pass_by_copie(test::USER);
pass_by_const_ref(test::USER);

g++ 4.7 下产生以下错误:

undefined reference to `test::USER'

我知道没有 test::USER 的实例。 (该行是故意注释的)


我有两个问题:

  1. 为什么需要 test::USER 的显式实例,而调用函数 pass_by_copie 不需要 test::NATIVE 的显式实例?

  2. 为什么我可以通过显式地从 test::USER 创建临时拷贝来调用 pass_by_rvalue_ref 而编译器无法(或不想)创建当用 test::USER 调用 pass_by_copie 时,他自己隐式复制了同一个拷贝?

谢谢

最佳答案

来自 C++11 的第 3.2 节:

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 and the lvalue-to-rvalue conversion is immediately applied.

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program

所以定义是必需的,因为 test::USER 是 odr-used,显然它是 odr-used 因为它不会立即进行左值到右值的转换。让我感到惊讶的是,对 pass_by_copie 的调用看起来像是在执行左值到右值的转换。

关于c++ - constexpr : literal class type copy behavior,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13766170/

相关文章:

c++ - openCV features2D 中的 `query` 和 `train` 是什么

Java静态final字段初始化顺序

java - 为什么在 Java 中使用类名而不是对象来访问类方法或变量更好?

c++ - 我可以在所有 MSVC >= 2013 上安全地使用哪些 SFINAE 技巧?

c++ - 静态类成员在动态库中与主应用程序不同

c++ - 代码::阻止 'mingw32-g++.exe 的执行失败

c++ - 如何初始化STL容器中存在的类的数据?

c++ - 在不使用 bitset 的情况下如何知道 C++ 中的位状态?

Android CMake 工具链错误?

c++ - 使用 MinGW 的 Qt Creator 找不到 std::shared_ptr