如何检查两个模板参数是否完全相同?

时间:2013-01-31 21:24:20

标签: c++ templates c++11

如果模板参数TU的类型完全相同,如何修改以下函数模板以使其返回42?

template<typename T,typename U>
int Foo()
{
  return 0;
}

4 个答案:

答案 0 :(得分:11)

使用std::is_same可以提供所需的行为:

#include <type_traits>

template<typename T,typename U>
int Foo()
{
    return std::is_same<T, U>::value ? 42 : 0;
}

答案 1 :(得分:4)

一种惯用的方法是将工作委托给detail命名空间中的辅助函数对象,对于TU相同的情况,您可以部分专门化(或者您可以在类模板中使用的任何其他编译时模式)。

namespace detail {

template<typename T, typename U>
struct foo
{
     int operator()() const
     {
         return 0;
     }
};

template<typename T>
struct foo<T, T>
{
     int operator()() const
     {
         return 42;
     }
};

} // namespace detail 

template<typename T, typename U>
int Foo()
{
     return detail::foo<T, U>()();
}

对于也具有可推导参数的函数(例如Foo(T x, U y)会),这结合了函数模板的参数推导的功能和类模板的特化功能,没有用户每个人都更聪明(嗯,你需要他们没有直接从namespace detail调用任何内容的约定

答案 2 :(得分:3)

为了完整答案,以下是如何在没有类的情况下在编译时做出这个选择:

namespace detail
{
    int Foo(std::true_type)
    {
        return 42;
    }

    int Foo(std::false_type)
    {
        return 0;
    }
}

template <typename T, typename U>
int Foo()
{
    return detail::Foo(std::is_same<T, U>());
}

当两个不同的代码路径对您的参数有不同的要求时,这种编译时分支很重要(尽管在这种情况下没有)。例如,在一个路径中,您使用成员函数x(),在另一个路径中使用y();或者你已经注意到,甚至完全“不同”的功能。

对我而言,这比管理课程简单得多。

答案 3 :(得分:1)

这个怎么样?

#include <iostream>

template<typename T,typename U>
struct Foo {
  int operator()()
  {
    return 0;
  }
};

template<typename T>
struct Foo<T, T> {
  int operator()()
  {
    return 42;
  }
};

int main() {
   std::cout << Foo<int, int>()() << std::endl;
   std::cout << Foo<int, double>()() << std::endl;
}