接受给定数量的双打的可变参数模板方法?
A variadic template method to accept a given number of doubles?
template <unsigned int N> class myclass
{
public:
template <typename... Args> void mymethod(Args... args)
{
// Do interesting stuff
}
};
我希望 mymethod
只被恰好 N 个双打调用。那可能吗?也就是说,假设我有:
myclass <3> x;
x.mymethod(3., 4., 5.); // This works
x.mymethod('q', 1., 7.); // This doesn't work
x.mymethod(1., 2.); // This doesn't work
我该如何完成?
对于参数数量约束,您可以轻松检查是否 sizeof...(Args) == N
但是要检查所有参数是否都是双精度数,您需要构建一个递归类型特征来检查每个参数的 std::is_same
.
template<typename...>
struct are_same : std::true_type
{};
template<typename T>
struct are_same<T> : std::true_type
{};
template<typename T, typename U, typename... Types>
struct are_same<T, U, Types...> :
std::integral_constant<bool, (std::is_same<T, U>::value && are_same<T, Types...>::value)>
{};
注意are_same
先声明然后specialized.
然后利用 SFINAE.
使用 std::enable_if
在方法 return 类型中实现约束
template <unsigned int N> class myclass
{
public:
template <typename... Args>
typename std::enable_if<(are_same<double, Args...>::value && sizeof...(Args) == N), void>::type
/* void */ mymethod(Args... args)
{
// Do interesting stuff
}
};
可以尝试如下操作:
#include <type_traits>
template<class T, class...>
struct all_same : std::true_type
{};
template<class T, class U, class... TT>
struct all_same<T, U, TT...>
: std::integral_constant<bool, std::is_same<T,U>{} && all_same<T, TT...>{}>
{};
template <unsigned int N> class myclass
{
public:
template <typename... Args>
typename std::enable_if<sizeof...(Args) == N, void >::type mymethod(Args... args)
{
static_assert(all_same<double, Args...>{},
"Not all args as Double");
}
};
template <unsigned int N> class myclass
{
public:
template <typename... Args> void mymethod(Args... args)
{
// Do interesting stuff
}
};
我希望 mymethod
只被恰好 N 个双打调用。那可能吗?也就是说,假设我有:
myclass <3> x;
x.mymethod(3., 4., 5.); // This works
x.mymethod('q', 1., 7.); // This doesn't work
x.mymethod(1., 2.); // This doesn't work
我该如何完成?
对于参数数量约束,您可以轻松检查是否 sizeof...(Args) == N
但是要检查所有参数是否都是双精度数,您需要构建一个递归类型特征来检查每个参数的 std::is_same
.
template<typename...>
struct are_same : std::true_type
{};
template<typename T>
struct are_same<T> : std::true_type
{};
template<typename T, typename U, typename... Types>
struct are_same<T, U, Types...> :
std::integral_constant<bool, (std::is_same<T, U>::value && are_same<T, Types...>::value)>
{};
注意are_same
先声明然后specialized.
然后利用 SFINAE.
使用std::enable_if
在方法 return 类型中实现约束
template <unsigned int N> class myclass
{
public:
template <typename... Args>
typename std::enable_if<(are_same<double, Args...>::value && sizeof...(Args) == N), void>::type
/* void */ mymethod(Args... args)
{
// Do interesting stuff
}
};
可以尝试如下操作:
#include <type_traits>
template<class T, class...>
struct all_same : std::true_type
{};
template<class T, class U, class... TT>
struct all_same<T, U, TT...>
: std::integral_constant<bool, std::is_same<T,U>{} && all_same<T, TT...>{}>
{};
template <unsigned int N> class myclass
{
public:
template <typename... Args>
typename std::enable_if<sizeof...(Args) == N, void >::type mymethod(Args... args)
{
static_assert(all_same<double, Args...>{},
"Not all args as Double");
}
};