如何禁用某些模板类型的 class 成员函数
How to disable a class member function for certain template types
看似简单,但是我对std::enable_if
的语法有些吃力
其实情况很简单。
具有模板参数 T
的模板 class
2 个函数不应为一种特定类型的 T
实现。
两个函数都没有参数或 return 值 T
一个函数接受 int
,另一个函数 return 接受 int
。
有什么简单的例子吗?
或者是否有另一个不使用 std::enable_if
的选项 (C++11)?
真的很简单。请记住使用默认为 class/struct 模板参数的另一个模板参数。
假设您想要一个包含两个成员 void foo<T>::bar1 (int)
和 int foo<T>::bar2 ()
的 class foo<T>
,并假设您想要 bar1()
和 bar2()
仅在 T
不同于 long
.
时实施
您可以进行如下操作
#include <type_traits>
template <typename T>
struct foo
{
template <typename U = T>
typename std::enable_if<false == std::is_same<U, long>::value>::type
bar1 (int)
{ }
template <typename U = T>
typename std::enable_if<false == std::is_same<U, long>::value, int>::type
bar2 ()
{ return 0; }
};
int main()
{
foo<int> fi;
foo<long> fl;
fi.bar1(0); // compile
fi.bar2(); // compile
// fl.bar1(0); // compilation error
// fl.bar2(); // compilation error
}
存在危险:有人可以绕过您的控制并显式 U
类型如下
foo<long> fl;
fl.bar1<long long>(0);
为避免此问题,您可以按如下方式改进 std::enable_if
测试
template <typename U = T>
typename std::enable_if
<sizeof(U) && (false == std::is_same<T, long>::value)>::type
bar1 (int)
{ }
template <typename U = T>
typename std::enable_if
<sizeof(U) && (false == std::is_same<T, long>::value), int>::type
bar2 ()
{ return 0; }
如果你可以使用 C++14 编译器,使用 std::enable_if_t
你可以避免一些 typename
和一些 if ::type
并简化代码如下
template <typename U = T>
std::enable_if_t<sizeof(U) && (false == std::is_same<T, long>::value)>
bar1 (int)
{ }
template <typename U = T>
std::enable_if_t<sizeof(U) && (false == std::is_same<T, long>::value), int>
bar2 ()
{ return 0; }
看似简单,但是我对std::enable_if
其实情况很简单。
具有模板参数 T
2 个函数不应为一种特定类型的 T
实现。
两个函数都没有参数或 return 值 T
一个函数接受 int
,另一个函数 return 接受 int
。
有什么简单的例子吗?
或者是否有另一个不使用 std::enable_if
的选项 (C++11)?
真的很简单。请记住使用默认为 class/struct 模板参数的另一个模板参数。
假设您想要一个包含两个成员 void foo<T>::bar1 (int)
和 int foo<T>::bar2 ()
的 class foo<T>
,并假设您想要 bar1()
和 bar2()
仅在 T
不同于 long
.
您可以进行如下操作
#include <type_traits>
template <typename T>
struct foo
{
template <typename U = T>
typename std::enable_if<false == std::is_same<U, long>::value>::type
bar1 (int)
{ }
template <typename U = T>
typename std::enable_if<false == std::is_same<U, long>::value, int>::type
bar2 ()
{ return 0; }
};
int main()
{
foo<int> fi;
foo<long> fl;
fi.bar1(0); // compile
fi.bar2(); // compile
// fl.bar1(0); // compilation error
// fl.bar2(); // compilation error
}
存在危险:有人可以绕过您的控制并显式 U
类型如下
foo<long> fl;
fl.bar1<long long>(0);
为避免此问题,您可以按如下方式改进 std::enable_if
测试
template <typename U = T>
typename std::enable_if
<sizeof(U) && (false == std::is_same<T, long>::value)>::type
bar1 (int)
{ }
template <typename U = T>
typename std::enable_if
<sizeof(U) && (false == std::is_same<T, long>::value), int>::type
bar2 ()
{ return 0; }
如果你可以使用 C++14 编译器,使用 std::enable_if_t
你可以避免一些 typename
和一些 if ::type
并简化代码如下
template <typename U = T>
std::enable_if_t<sizeof(U) && (false == std::is_same<T, long>::value)>
bar1 (int)
{ }
template <typename U = T>
std::enable_if_t<sizeof(U) && (false == std::is_same<T, long>::value), int>
bar2 ()
{ return 0; }