了解别名模板

2023-12-05

我问了一个question其中有几个对代码的引用:

template <typename...>
using void_t = void;

我相信我有一个普遍的误解别名模板:

为什么你不直接评估你传递到别名模板中的任何模板参数enable_if_t or conditional_t陈述?

上面的代码只是做一个enable_if_t一次使用多个模板参数?

其次,我认为我对角色的理解存在一定的误解。void_t. 这条评论指出 C++17 标准定义void_t。这是我不明白的:

Isn't void_t只是一个任意的名字?如果我还必须定义template <typename...> using void_t = void;无论我打算使用什么地方void_t标准化任意名称有什么意义?


在巴里的链接问题的示例中:

template<typename T, typename = void>
struct has_to_string
: std::false_type { };

template<typename T>
struct has_to_string<T, 
    void_t<decltype(std::to_string(std::declval<T>()))>
    > 
: std::true_type { };

void_t只是用来翻译推导的类型decltype to void以便它与默认参数匹配primary模板定义。 SFINAE 全部由decltype表达。您可以轻松地执行以下操作:

//use , void() instead of wrapping in void_t
//this uses the comma operator to check the type of the to_string call, then change the type to void
decltype(std::to_string(std::declval<T>()), void())

前一个版本更容易阅读并且void_t不需要decltype上班。

If void_t在您的实现中可用,您无需重新定义它。当它标准化后,它将像标准中的任何其他别名模板一样可用。

这样想:如果T is int,其中有一个有效的std::to_string重载,扣除将如下所示:

has_to_string<int> -> has_to_string<int,void>因为默认参数。所以让我们寻找以下专业has_to_string与这些论点。

template<typename T>
struct has_to_string<T, 
    void_t<decltype(std::to_string(std::declval<T>()))>
    > 
: std::true_type { };

好吧,这对某些人来说是部分专业化T和一些依赖类型。让我们计算一下该类型:

void_t<decltype(std::to_string(std::declval<T>()))>
//std::to_string(int&&) is valid and returns a std::string
void_t<std::string>
//void_t changes types to void
void

现在我们的专业化是这样的:

template<>
struct has_to_string<int,void>
: std::true_type { };

这与我们的实例化相匹配has_string<int,void>, so has_to_string<int>继承自std::true_type.

现在想想当T is struct Foo{};。再次,让我们计算出依赖类型:

void_t<decltype(std::to_string(std::declval<T>()))>
//wait, std::to_string(Foo&&) doesn't exist
//discard that specialization

放弃该专业化后,我们回到主模板:

template<typename T, typename = void>
struct has_to_string
: std::false_type { };

So has_to_string<Foo>继承自std::false_type.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解别名模板 的相关文章

随机推荐