如何限制模板中的类型名 [英] How to restrict typenames in template
问题描述
有一个可以接受4种不同类型的函数。它们的实现非常相似。
template<类型名T>
void foo(std :: string&& name,T value){
// ...
}
typename T
必须是4种预定义类型之一。
是否可以用C ++编写?
< type_traits>
让你将逻辑推广到类模板。这是如何工作的我们取模板参数 T
和参数包 Ts
,我们开始检查 T
与类型列表的 Head
相同。如果找到匹配,我们继承 std :: true_type
,我们就完成了。如果没有找到匹配,我们弹出头部并递归地实例化 Ts
的尾部的相同模板。最终,如果没有找到匹配,参数包大小将下降到零,编译器将实例化继承自 std :: false_type
的基本模板类。请检查此视频,以便更好地进行,并由Walter E. Brown先生进行深入解释。
模板< class T,class ...> struct is_any_of:std :: false_type {};
template< class T,class Head,class ... Tail>
struct is_any_of< T,Head,Tail ...> ;: std :: conditional_t<
std :: is_same< T,Head> :: value,
std :: true_type,
is_any_of< T,Tail ...>
{};
现在我们可以使用 enable_if 。
include< type_traits>
#include< string>
template<
class T,
class = std :: enable_if_t< is_any_of< T,int,float,unsigned,double> :: value>
>
void foo(std :: string&& str,T value){}
int main()
{
foo :: string {hello},3);
foo(std :: string {world},'0'); //编译时错误
}
SFANIE是一种语言功能,
标准库组件std :: enable_if允许使用或滥用某些人说要实现您的要求<用于创建替换失败,以便基于在编译时评估的条件来启用或禁用特定的重载。
FYI http://en.cppreference.com/w/cpp/language/ sfinae 。
请注意, std :: conditional_t<>
std :: conditional<> :: type 和 std :: enable_if_t< code> std :: enable_if<> :: type
。你可以简单地在代码中替换这些,但应该在 enable_if
之前放置 typename
Have a function which can accept 4 different types. And their implementations are very similar.
template< typename T >
void foo( std::string &&name, T value ){
//...
}
typename T
must be one of 4 predefined types. Other typenames is not acceptable, and should be restricted at compile-time.
Is it possible to write in C++?
<type_traits>
let you generalize your logic into class template. How this works is we take template parameter T
and parameter pack of Ts
and we start checking if T
is same to Head
of the list of types. If match is found, we inherit from std::true_type
and we are done. If no match is found, we pop the head and recursively instantiate same template with tail of Ts
. Eventually, if no match is found at all, parameter pack size will drop to zero and the compiler will instantiate base template class that inherit from std::false_type
. Please check this video for much better and in dept explanation by Mr. Walter E. Brown.
template<class T, class...> struct is_any_of: std::false_type{};
template<class T, class Head, class... Tail>
struct is_any_of<T, Head, Tail...>: std::conditional_t<
std::is_same<T, Head>::value,
std::true_type,
is_any_of<T, Tail...>>
{};
Now we can SFINAE over, using enable_if in almost English wording.
#include <type_traits>
#include <string>
template<
class T,
class = std::enable_if_t<is_any_of<T, int, float, unsigned, double>::value>
>
void foo(std::string &&str, T value) {}
int main()
{
foo(std::string{"hello"}, 3);
foo(std::string{"world"}, '0'); //compile-time error
}
SFANIE is a language feature, a tool, that's used or abused some say to achieve what you ask for,
The standard library component std::enable_if allows for creating a substitution failure in order to enable or disable particular overloads based on a condition evaluated at compile time. FYI http://en.cppreference.com/w/cpp/language/sfinae.
Note that std::conditional_t<>
and std::enable_if_t<>
are shorthanded from std::conditional<>::type
and std::enable_if<>::type
respectively. You could simple replace these in code, but should put typename
keyword before enable_if
then.
这篇关于如何限制模板中的类型名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!