特征中静态成员的初始化

Initialisation of static members in traits

本文关键字:初始化 静态成员 特征      更新时间:2023-10-16

我一直读到你可以定义一个特征,比如

enum MyEnum { val_1, val_2, val_3 };
template< typename T > 
struct my_trait { 
  static const MyEnum value = MyEnum::val_1;
};

然后专门化

template<> 
struct my_trait < void >{ 
  static const MyEnum value = val_3; 
};

当我尝试它时,我总是收到链接器错误,因为未定义static成员,因此我必须在源文件中明确将其专用为

MyEnum my_trait < void >::value = val_3;

并将标题中的定义更改为

template<> 
struct is_void< void >{ 
  static const MyEnum value; 
};

有没有办法直接在标题中定义特征,而不必在标题中重新定义它?

不完全是你问题的答案,但是...在您的示例中(如果您可以使用 C++11 编译器(,您可以使用 std::integral_constant .

完整示例

#include <iostream>
#include <type_traits>
enum MyEnum { val_1, val_2, val_3 };
template< typename T > 
struct my_trait : public std::integral_constant<MyEnum, MyEnum::val_1>
 { };
template<> 
struct my_trait<void> : public std::integral_constant<MyEnum, MyEnum::val_3>
 { };
int main ()
 {
   std::cout << my_trait<void>::value << std::endl; // print 2 (aka val_3)
   std::cout << my_trait<int>::value << std::endl;  // print 0 (aka val_1)
 }

这将导致链接器错误:

std::cout << &is_void<void>::value << std::endl;

因为你使用value - 这意味着你想要它的地址。我不确定,但这也可能发生在引用中 - 因为它们可能在内部作为指针实现。因此,在 c++14 之前,您必须在实现文件中定义value

从 C++17 开始,您可以使用内联变量将其全部保存在一个地方,即使您需要使用它:

template< typename T > 
struct is_void{ 
  inline static const bool value = false;
  ^^^^^^ 
};