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

How to check if two template parameters are exactly the same?

本文关键字:是否 参数 两个 何检查 检查      更新时间:2023-10-16
如何

修改以下函数模板,使其在模板参数TU类型完全相同时返回 42?

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

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

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

一种惯用的方法是将工作委托给 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调用任何东西)

为了答案的完整性,以下是在没有类的情况下在编译时做出此选择的方法:

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();或者正如您所指出的,甚至是完全不同的"功能。

对我来说,这比管理一个班级要简单得多。

这个呢?

#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;
}
相关文章: