是否可以将'enable_if'和'is_same'与可变参数函数模板一起使用?(Is it possible to use 'enable_if' and 'is_same' with variadic function templates?)
这两个非可变函数模板进行编译:
template <typename T, typename U> typename std::enable_if<std::is_same<U, int>::value, void>:: type testFunction(T a, U b) { std::cout << "b is integer\n"; } template <typename T, typename U> typename std::enable_if<std::is_same<U, float>::value, void>:: type testFunction(T a, U b) { std::cout << "b is float\n"; }但是,类似的可变参数模板不能编译:
template <typename T, typename... U> typename std::enable_if<std::is_same<U, int>::value, void>:: type testFunction(T a, U... bs) { std::cout << "bs are integers\n"; } template <typename T, typename... U> typename std::enable_if<std::is_same<U, float>::value, void>:: type testFunction(T a, U... bs) { std::cout << "bs are floats\n"; }也许我正在尝试做一些无法完成的事情。 我知道使用初始化器列表可以实现类似的功能,但是我想避免初始化器列表参数所需的大括号。
These two non-variadic function templates do compile:
template <typename T, typename U> typename std::enable_if<std::is_same<U, int>::value, void>:: type testFunction(T a, U b) { std::cout << "b is integer\n"; } template <typename T, typename U> typename std::enable_if<std::is_same<U, float>::value, void>:: type testFunction(T a, U b) { std::cout << "b is float\n"; }however, similar variadic templates do not compile:
template <typename T, typename... U> typename std::enable_if<std::is_same<U, int>::value, void>:: type testFunction(T a, U... bs) { std::cout << "bs are integers\n"; } template <typename T, typename... U> typename std::enable_if<std::is_same<U, float>::value, void>:: type testFunction(T a, U... bs) { std::cout << "bs are floats\n"; }Maybe I am trying to do something that cannot be done. I know that similar functionality can be achieved using initializer lists, but I would like to avoid curly brackets required for initializer list arguments.
最满意答案
是。 你可以在C ++ 17中使用fold表达式 :
template <typename T, typename... U> typename std::enable_if<(std::is_same<U, float>::value && ...), void>:: type testFunction(T a, U... bs) { std::cout << "bs are floats\n"; }在C ++ 11中,你可以重新实现std::conjunction :
template<class...> struct conjunction : std::true_type { }; template<class B1> struct conjunction<B1> : B1 { }; template<class B1, class... Bn> struct conjunction<B1, Bn...> : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {}; template <typename T, typename... U> typename std::enable_if< std::conjunction_v<std::is_same<U, float>::value...>, void >::type testFunction(T a, U... bs) { std::cout << "bs are floats\n"; }Yes. You can use a fold expression in C++17:
template <typename T, typename... U> typename std::enable_if<(std::is_same<U, float>::value && ...), void>:: type testFunction(T a, U... bs) { std::cout << "bs are floats\n"; }In C++11, you can reimplement std::conjunction:
template<class...> struct conjunction : std::true_type { }; template<class B1> struct conjunction<B1> : B1 { }; template<class B1, class... Bn> struct conjunction<B1, Bn...> : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {}; template <typename T, typename... U> typename std::enable_if< std::conjunction_v<std::is_same<U, float>...>, void >::type testFunction(T a, U... bs) { std::cout << "bs are floats\n"; }更多推荐
发布评论