了解别名模板 [英] Understanding Alias Templates
问题描述
我问了一个问题,其中有多个代码引用:
I asked a question that has several references to the code:
template <typename...>
using void_t = void;
我相信我有一个一般误解别名模板:
I believe I have a generally misunderstand alias templates:
您是否在 enable_if_t
或 conditional_t
语句中传递别名模板?
Why wouldn't you just evaluate whatever template parameter you're passing into an alias template in an enable_if_t
or conditional_t
statement?
上面的代码只是一次对多个模板参数执行 enable_if_t
?
Is the code above just about doing an enable_if_t
on multiple template parameters at once?
其次,我相信我对 void_t
的作用有一个具体的误解。 此评论说明C ++ 17标准定义 void_t
。这里是我不能得到的:
Secondly, I believe that I have a specific misunderstanding of the role of void_t
. This comment states that the C++17 standard defines void_t
. Here's what I don't get:
不是 void_t
只是一个任意名称?如果我还需要定义 template< typename ...>使用void_t = void;
无论我计划使用 void_t
什么是标准化任意名称的意义?
Isn't void_t
just an arbitrary name? If I still have to define template <typename...> using void_t = void;
wherever I plan to use void_t
what's the point of standardizing an arbitrary name?
推荐答案
我不认为所示的例子真的显示了 void_t
显示一个用例,但是当您查看
I don't think the shown example really shows what void_t
is good for as it only shows one use case, but when you look at
template<typename T>
struct has_to_string<T,
void_t<decltype(std::to_string(std::declval<T>()))>
>
: std::true_type { };
与
template<typename T>
struct has_to_string<T,
decltype(std::to_string(std::declval<T>()), void())
>
: std::true_type { };
对于此语句:
前一个版本更容易阅读,
void_t
不需要decltype
工作。
我认为可读性的优势很小,第二部分没有意义,当 decltype
不起作用,SFINAE会按预期插入。
I think the advantage in readability is quite small and the second part makes no sense, when decltype
doesn't work, SFINAE kicks in as expected.
其中 void_t
有用的是提案中的一个:
One example where void_t
is more useful is the one from the proposal:
// primary template handles types that have no nested ::type member
template< class, class = void_t<> >
struct has_type_member
: std::false_type { };
// specialization recognizes types that do have a nested ::type member
template< class T >
struct has_type_member<T, void_t<typename T::type>>
: std::true_type { }
正如你所看到的, void_t
以增加可读性,因为它现在匹配专业化。这不是绝对必要的,但我喜欢它。真正的力量来自于你想到的替代品。没有 void_t
,专业化现在更复杂:
As you can see, even the primary template uses void_t
to increase the readability as it now matches the specialization. That is not strictly necessary, but I like it. The real power comes when you think about the alternatives. Without void_t
, the specialization is now more complicated:
template< class T >
struct has_type_member<T, decltype(typename T::type, void())>
: std::true_type { }
不能作为 T :: type
命名一个类型,而不是一个表达式。因此,您需要
wouldn't work as T::type
names a type, not an expression. You therefore need
template< class T >
struct has_type_member<T, decltype(std::declval<typename T::type>(), void())>
: std::true_type { }
整个表达式变得更长,更棘手可能会遇到你忘记处理的边缘情况。这是 void_t
真正有帮助的地方,其他用途只是一个小小的改进,它们提高了一致性。
The whole expression becomes longer, more tricky and it might suffer from edge-cases you forgot to handle. This is where void_t
really helps, the other uses are then just a small improvement and they increase consistency.
这篇关于了解别名模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!