如何根据模板参数是否具有别名来专门化类型

How to specialize a type based on whether a template parameter has an alias

本文关键字:别名 专门化 类型 是否 何根 参数      更新时间:2023-10-16

我希望能够根据容器是否具有指定的类型定义来专门化类型,例如

class SomethingElse {};
class Something {
    using Type = int;
};
static constexpr bool value = ChooseIfType<Something>::value;

当类型没有类型定义Type时,ChooseIfType是否有方法返回false ?

我觉得有一种简单的方法可以做到这一点,但是我想不出来。

谢谢!

使用std::void_t(或c++ 11替代):

template<typename T, typename = std::void_t<>>
struct ChooseIfType : std::false_type {};
template<typename T>
struct ChooseIfType<T, std::void_t<typename T::Type>> : std::true_type {};

现场演示

该方案利用了SFINAE。默认值永远不会是畸形的,并且会创建一个值为false的trait。编译器尝试匹配所有模板特化(在本例中只有一个)。如果T有一个成员类型Type,那么ChooseIfType<T, void_t<typename T::Type>>ChooseIfType<T, void_t<>>更专门化。如果没有,那么它就不是一个可行的专门化,并选择默认值,但是替代失败不是错误。

根据cppreference, c++ 11 void_t的实现看起来像这样:

template<typename... Ts> struct make_void { typedef void type;};
template<typename... Ts> using void_t = typename make_void<Ts...>::type;