rsk*_*k82 4 c++ polymorphism templates function c++11
我知道如何使用模板的任何数据类型:
template<typename T>
T myFunc(T data) { ... }
Run Code Online (Sandbox Code Playgroud)
但是,有没有办法设定的允许的类型缩小到例如int和char或std::string和std::wstring,所以编译器将抛出一个错误,遇到不允许参数类型的时候,我会得到编译时间,而不是运行时错误?
编辑:非常感谢ecatmur,现在我理解了整个概念.
template<typename itemA_type, typename itemB_type>
typename std::enable_if<
(
std::is_same<itemA_type, int>::value ||
std::is_same<itemA_type, char>::value) &&
(
std::is_same<itemB_type, std::string>::value ||
std::is_same<itemB_type, std::wstring>::value ||
std::is_same<itemB_type, const char*>::value ||
std::is_same<itemB_type, const wchar_t*>::value
) ,
void
>::type
myFunction(itemA_type itemA, itemB_type itemB) {
using namespace std;
cout << itemA << itemB << endl;
}
Run Code Online (Sandbox Code Playgroud)
jro*_*rok 10
拿这个实用程序特质类:
template<typename T, typename U, typename... Us>
struct is_any_of
: std::integral_constant<
bool,
std::conditional<
std::is_same<T,U>::value,
std::true_type,
is_any_of<T,Us...>
>::type::value
>
{ };
template<typename T, typename U>
struct is_any_of<T,U> : std::is_same<T,U>::type { };
Run Code Online (Sandbox Code Playgroud)
然后你可以在静态断言中使用它:
template<typename T>
T myFunc(T data)
{
static_assert( is_any_of<T, int, char, std::string>{}, "T not allowed");
}
Run Code Online (Sandbox Code Playgroud)
如果您觉得更合适,可以使用std::is_convertible或std::is_constructible代替std::is_same.
你可以使用 SFINAE 做到这一点:
#include <type_traits>
template<class T> struct AllowedType : std::false_type {};
template<> struct AllowedType<int> : std::true_type {}; // Add more specializations.
template<> struct AllowedType<char> : std::true_type {}; // Add more specializations.
template<typename T>
typename std::enable_if<AllowedType<T>::value, T>::type
myFunc(T data);
int main() {
myFunc(1); // int, okay
myFunc('c'); // char, okay
myFunc(1.); // double, fail
}
Run Code Online (Sandbox Code Playgroud)
或者您可以将允许的类型集指定为boost::mpl::vector<>序列(与上述效果相同):
#include <boost/mpl/vector.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/utility/enable_if.hpp>
typedef boost::mpl::vector<int, char> allowed_type_set;
template<typename T>
typename boost::enable_if<boost::mpl::contains<allowed_type_set, T>, T>::type
myFunc(T data);
int main() {
myFunc(1); // int, okay
myFunc('c'); // char, okay
myFunc(1.); // double, fail
}
Run Code Online (Sandbox Code Playgroud)
使用enable_if和的简单解决方案is_same:
template<typename T>
typename std::enable_if<
std::is_same<T, int>::value ||
std::is_same<T, char>::value,
T>::type
myFunc(T data) { ... }
Run Code Online (Sandbox Code Playgroud)
随着谓词T变得越来越复杂(例如,你只是允许string和wstring/或其他特化basic_string?)你可能开始想要编写更复杂的谓词元函数; 但就目前而言,一个简单的表达可能就足够了.