在 C++03 中,如何根据类型特征有条件地声明模板 class 的静态数据成员
In C++03, how to conditionally declare a static data member of a template class, based on type traits
背景
考虑到我想 在 C++03 中实现以下人为构造:
(+)
template< typename T > // parameter list must contain T but may otherwise modified
struct foo;
If the type trait dummy_trait<T>::value
over the template parameter
T
of foo
is true
, then foo
should contain a static data member
named value
, of type T
, initialized with the integer literal expression 42
; otherwise there should be no static data
member named value
.
例如以下 dummy_trait
(实际虚拟特征可能不同):
template< typename T >
struct dummy_trait { static const bool value = false; };
template<>
struct dummy_trait<int> { static const bool value = true; };
问题
- 除了以下两种方法之外,是否还有其他(可能更合适的)替代方案来实现 (+)?
- 使用以下两种方法中的任何一种时,是否有任何陷阱或方面需要仔细牢记?
我自己的方法
使用助手
template< bool B, typename T = void >
struct enable_if {};
template< typename T >
struct enable_if<true, T> { typedef T type; };
例如使用部分 class 模板专业化:
// (A)
template< typename T, typename Enable = void >
struct foo {};
template< typename T >
struct foo<T, typename enable_if<dummy_trait<T>::value>::type > {
static const T value = 42;
};
或者例如利用 SFINAE 在静态数据成员的声明中引入条件性(特征)错误:
// (B)
template< typename T >
struct foo {
static const typename enable_if<
dummy_trait<T>::value, T >::type value = 42;
};
如果我没记错的话,上面的 (A)
将允许使用 foo
也用于类型 T
的实例化,其中 dummy_trait<T>::value
是 false
(尽管将没有 foo
的 value
成员),而如果使用 (B)
.
则根本不可能进行此类实例化
Are there any other (possibly more appropriate) alternatives to implement (+), in addition to the two approaches below (leveraging SFINAE)?
与您的解决方案 (A) 差别不大,但是...您可以通过继承获得结果
template <typename T>
struct foo : public bar<T>
{ };
其中bar
如下
template <typename T, bool = dummy_trait<T>::value>
struct bar { };
template <typename T>
struct bar<T, true> { static const T value = 42; };
您还可以将 bar
视为获得 foo
.
的更简单方法(无 enable_if
)
Are there any pitfalls or aspects to carefully bear in mind using any of the two approaches below?
我看到的唯一陷阱是您刚才看到的那个:(B) 方法不起作用,因为当 dummy_trait<T>::value
为 false
时您无法定义 foo
。
我的意思是...(B) 不是 SFINAE,因为替换失败,在这种情况下,是一个错误。
背景
考虑到我想 在 C++03 中实现以下人为构造:
(+)
template< typename T > // parameter list must contain T but may otherwise modified struct foo;
If the type trait
dummy_trait<T>::value
over the template parameterT
offoo
istrue
, thenfoo
should contain a static data member namedvalue
, of typeT
, initialized with the integer literal expression42
; otherwise there should be no static data member namedvalue
.
例如以下 dummy_trait
(实际虚拟特征可能不同):
template< typename T > struct dummy_trait { static const bool value = false; }; template<> struct dummy_trait<int> { static const bool value = true; };
问题
- 除了以下两种方法之外,是否还有其他(可能更合适的)替代方案来实现 (+)?
- 使用以下两种方法中的任何一种时,是否有任何陷阱或方面需要仔细牢记?
我自己的方法
使用助手
template< bool B, typename T = void >
struct enable_if {};
template< typename T >
struct enable_if<true, T> { typedef T type; };
例如使用部分 class 模板专业化:
// (A)
template< typename T, typename Enable = void >
struct foo {};
template< typename T >
struct foo<T, typename enable_if<dummy_trait<T>::value>::type > {
static const T value = 42;
};
或者例如利用 SFINAE 在静态数据成员的声明中引入条件性(特征)错误:
// (B)
template< typename T >
struct foo {
static const typename enable_if<
dummy_trait<T>::value, T >::type value = 42;
};
如果我没记错的话,上面的 (A)
将允许使用 foo
也用于类型 T
的实例化,其中 dummy_trait<T>::value
是 false
(尽管将没有 foo
的 value
成员),而如果使用 (B)
.
Are there any other (possibly more appropriate) alternatives to implement (+), in addition to the two approaches below (leveraging SFINAE)?
与您的解决方案 (A) 差别不大,但是...您可以通过继承获得结果
template <typename T>
struct foo : public bar<T>
{ };
其中bar
如下
template <typename T, bool = dummy_trait<T>::value>
struct bar { };
template <typename T>
struct bar<T, true> { static const T value = 42; };
您还可以将 bar
视为获得 foo
.
enable_if
)
Are there any pitfalls or aspects to carefully bear in mind using any of the two approaches below?
我看到的唯一陷阱是您刚才看到的那个:(B) 方法不起作用,因为当 dummy_trait<T>::value
为 false
时您无法定义 foo
。
我的意思是...(B) 不是 SFINAE,因为替换失败,在这种情况下,是一个错误。