一个可行的方法就是利用这一点:
别名模板永远不会被模板参数推导得出推断模板的模板时参数。
http://en.cppreference.com/w/cpp/language/type_alias
因此,与类型特征像
template<
typename T,
template<typename...> class Template
>
struct instantiated_from
: std::false_type {};
template<
template<typename...> class Template,
typename... Arguments
>
struct instantiated_from<Template<Arguments...>, Template>
: std::true_type {};
我们可以肯定的是,当我们通过Alias<int>
作为第一个模板参数和Alias
为第二,那么编译器不会选择专业化。这立即给我们:
template<
template<typename...> class Template,
typename... Args
>
struct is_alias_template
: std::integral_constant<
bool,
! instantiated_from<Template<Args...>, Template>::value
>
{};
有了这个,我们可以 - 给出一些合适的模板参数 - 检测模板是否为别名模板或不:
int main() {
static_assert( is_alias_template<Alias, int>::value, "");
static_assert(! is_alias_template<Normal, int>::value, "");
static_assert( is_alias_template<Alias, Alias<int>>::value, "");
static_assert( is_alias_template<Alias, Normal<int>>::value, "");
static_assert(! is_alias_template<Normal, Alias<int>>::value, "");
static_assert(! is_alias_template<Normal, Normal<int>>::value, "");
}
这里的主要缺点是当然的那个人需要知道一组合适的模板参数。只是猜测(或使用int
)将不适用于具有固定号码(> 1)模板参数的模板。
此外,这不适用于具有非类型(或模板)模板参数的模板(别名或不模板)。