检查第n个可变参数模板参数是否属于某种类型

时间:2017-11-16 20:29:51

标签: c++ c++11 templates variadic-templates

我想在下面的 C ++ 11 中实现类似same_type()函数的东西(这是我到目前为止所尝试的但是它无法处理下面提到的用例) 。 该函数用于检查T是否与Args的第n个参数的类型相同,当前n = 0应该足以满足我的要求,尽管n =其他有意义的值将有更好的东西(如果不是直截了当,则不是很重要)。

template<typename T, typename... Args>
struct MyClass
{
    // check if T is of the same type of the n-th argument of Args
    bool same_type() {
        // currently, I only check the first argument
        // but if possible, it would be more useful to extend 
        // this function to check the n-th argument
        return std::is_same<T,typename std::tuple_element<0, std::tuple<Args...> >::type>;
    }
};

我已经查看了this answer,但它没有考虑以下用例。

用例:

1.使用引用和const限定符:

MyClass<int,const int&> c;
// expect to see 1, type of int should match const int&, i.e. reference or const should NOT affect the result
std::cout<<c.same_type();    

2.使用时不提供参数:

MyClass<int> c;
// expect to see 0 as there is no variadic argument provided to compare with int
std::cout<<c.same_type();    

2 个答案:

答案 0 :(得分:1)

我建议开发一个类型特征isSameNth如下

template <std::size_t, typename...>
struct isSameNth;

template <std::size_t N, typename T, typename A0, typename ... As>
struct isSameNth<N, T, A0, As...> : public isSameNth<N-1U, T, As...>
 { };

template <std::size_t N, typename T>
struct isSameNth<N, T> : public std::false_type
 { };

template <typename T, typename A0, typename ... As>
struct isSameNth<0U, T, A0, As...> : public std::is_same<
   typename std::remove_reference<T>::type const,
   typename std::remove_reference<A0>::type const>
 { };

在模板静态方法中转换same_type()(其中模板值为N

template <typename T, typename... Args>
struct MyClass
 {
   template <std::size_t N>
   static constexpr bool same_type()
    { return isSameNth<N, T, Args...>::value; }
 };

以下是完整示例(符合C ++ 11)

#include <type_traits>

template <std::size_t, typename...>
struct isSameNth;

template <std::size_t N, typename T, typename A0, typename ... As>
struct isSameNth<N, T, A0, As...> : public isSameNth<N-1U, T, As...>
 { };

template <std::size_t N, typename T>
struct isSameNth<N, T> : public std::false_type
 { };

template <typename T, typename A0, typename ... As>
struct isSameNth<0U, T, A0, As...> : public std::is_same<
   typename std::remove_reference<T>::type const,
   typename std::remove_reference<A0>::type const>
 { };

template <typename T, typename... Args>
struct MyClass
 {
   template <std::size_t N>
   static constexpr bool same_type()
    { return isSameNth<N, T, Args...>::value; }
 };

int main ()
 {
   static_assert(
      false == MyClass<int, long, int, short>::template same_type<0U>(), "!");
   static_assert(
      true == MyClass<int, long, int, short>::template same_type<1U>(), "!");
   static_assert(
      false == MyClass<int, long, int, short>::template same_type<2U>(), "!");

   static_assert(
      true == MyClass<int const, int &>::template same_type<0U>(), "!");

   static_assert(
      false == MyClass<int const &>::template same_type<0U>(), "!");
 }

答案 1 :(得分:1)

我认为您希望检查兼容性而非“同一性”。这是一种方式:

sum(alpha_beta)
[1] -4.440892e-16