有一个可以接受4种不同类型的功能。它们的实现非常相似。
template< typename T >
void foo( std::string &&name, T value ){
//...
}
typename T
必须是4种预定义类型之一。其他类型名称是不可接受的,应在编译时加以限制
是否可以用C ++编写?
答案 0 :(得分:5)
我至少可以想到三种方式,不管怎么说。
首先:
namespace internal {
template< typename T >
void foo_impl( std::string &&name, T value ) {
// actual implementation here
}
}
void foo(std::string &&name, SpecialType1 value ) {
internal::foo_impl(std::forward<std::string>(name), value);
}
void foo(std::string &&name, SpecialType2 value ) {
internal::foo_impl(std::forward<std::string>(name), value);
}
第二
template< typename T >
typename std::enable_if<std::is_same<T, SpecialType1>::value ||
std::is_same<T, SpecialType2>::value >::type
foo( std::string &&name, T value ){
//implementation here
}
第三
template< typename T >
void foo(std::string &&name, T value){
static_assert(std::is_same<T, SpecialType1>::value ||
std::is_same<T, SpecialType2>::value,
"wrong template argument");
//implementation here
}
答案 1 :(得分:1)
我看到人们做过的一件事就是使用std::enable_if
。我不确切知道您的4种类型是什么,因此这是一个包含int
和float
两种类型的示例。
using myType = std::enable_if<
std::is_same<int, T>::value ||
std::is_same<float, T>::value, T >::type;
myType
仅在T
完全是int
或float
时才存在。希望有所帮助!
答案 2 :(得分:1)
<type_traits>
让您将逻辑推广到类模板中。这是如何工作的我们采用模板参数T
和参数包Ts
,我们开始检查T
是否与类型列表的Head
相同。如果找到匹配,我们继承std::true_type
,我们就完成了。如果找不到匹配项,我们会弹出头部并以Ts
的尾部递归实例化相同的模板。最终,如果根本找不到匹配项,参数包大小将降至零,编译器将实例化从std::false_type
继承的基本模板类。请更好地查看video以及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...>>
{};
现在我们可以使用enable_if几乎用英文写法来完成SFINAE。
#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是一种语言功能,一种工具,用于或滥用有人说要实现你的要求,
标准库组件std :: enable_if允许创建替换失败,以便根据在编译时评估的条件启用或禁用特定的重载。 仅供参考http://en.cppreference.com/w/cpp/language/sfinae。
请注意,std::conditional_t<>
和std::enable_if_t<>
分别来自std::conditional<>::type
和std::enable_if<>::type
。您可以在代码中简单地替换这些,但应在typename
之前添加enable_if
关键字。