【发布时间】:2012-10-03 06:08:07
【问题描述】:
假设我有这些声明
template<typename T> class User;
template<typename T> class Data;
并希望为T = Data<some_type> 实现User<> 以及从Data<some_type> 派生的任何类,但也允许在别处定义的其他特化。
如果我还没有类模板 User<> 的声明,我可以简单地
template<typename T,
typename A= typename std::enable_if<is_Data<T>::value>::type>
class User { /*...*/ };
在哪里
template<template<typename> data>> struct is_Data
{ static const bool value = /* some magic here (not the question) */; };
但是,这有两个模板参数,因此与之前的声明冲突,其中 User<> 仅使用一个模板参数声明。还有什么我可以做的吗?
(注意
template<typename T,
typename A= typename std::enable_if<is_Data<T>::value>::type>
class User<T> { /*...*/ };
不起作用(默认模板参数不能用于部分特化), 也没有
template<typename T> class User<Data<T>> { /*...*/ };
因为它不允许派生自 Data<> 的类型,所以也不允许
template<typename T>
class User<typename std::enable_if<is_Data<T>::value,T>::type>
{ /*...*/ };
因为模板参数T 不用于偏特化。)
【问题讨论】:
-
SFINAE 可以用于选择模板专业,请参阅en.cppreference.com/w/cpp/types/enable_if
-
可以!我学到了一些东西。
-
澄清一下:您希望能够为任何
Data<>或子类实例化User<>,但对于任何其他类型不?User<int>应该编译失败吗? -
@Walter 在这种情况下,为什么还要为部分专业化而烦恼呢?你不能在非专业版本中使用静态断言吗?
-
请注意,对这种 SFINAE 使用
std::enable_if有点迂回。使用typename = std::true_type作为默认参数,您可以编写与<T, typename is_foo<T>::type>匹配的部分规范,假设is_foo是例如标准意义上的 UnaryTypeTrait(<type_traits>中的任何特征都是这样工作的)。
标签: c++ templates c++11 sfinae