【问题标题】:Metaprogramming with std::is_same使用 std::is_same 进行元编程
【发布时间】:2014-12-16 12:04:57
【问题描述】:

是否可以在没有模板专业化的情况下进行如下编译?

template <class T> 
class A {
public:
  #if std::is_same<T,int>
  void has_int() {}
  #elif std::is_same<T,char>
  void has_char() {}
  #endif
};
A<int> a; a.has_int();
A<char> b; b.has_char();

【问题讨论】:

标签: c++ template-meta-programming


【解决方案1】:

是的。制作函数模板,然后使用std::enable_if有条件地启用它们:

#include <type_traits>

template <class T> 
class A {
public:

  template<typename U = T>
  typename std::enable_if<std::is_same<U,int>::value>::type
  has_int() {}

  template<typename U = T>
  typename std::enable_if<std::is_same<U,char>::value>::type
  has_char() {}
};

int main()
{
    A<int> a;
    a.has_int();   // OK
    // a.has_char();  // error
}

the other answer 的解决方案可能不可行,如果类很大并且有许多功能需要不管T。但是您可以通过从仅用于这些特殊方法的另一个类继承来解决此问题。然后,您可以只专门化该基类。

在 C++14 中,有方便的类型别名,因此语法可以变成:

std::enable_if_t<std::is_same<U, int>::value>

还有 C++17,甚至更短:

std::enable_if_t<std::is_same_v<U, int>>

【讨论】:

  • 好东西!非常感谢。
  • 您可以添加,在 C++14 中您可以编写 std:::enable_if_t,在 C++17 中甚至可以编写 std::is_same_v,以便摆脱 typename ... ::type::value 的冗长。
【解决方案2】:

是的,使用模板专业化:

template <class T> 
class A;

template <> 
class A<int>
{
    void had_int(){}
};

template <> 
class A<char>
{
    void had_char(){}
};

【讨论】:

  • 有什么办法不用两次重写相同的代码?
  • 您可以通过模板特化引入新的类成员声明吗?这对我来说是新事物。
  • @ZeroCool 两次不是同一个代码。当模板参数不同时,您将实现不同的行为。
  • @5gon12eder 静态如果在委员会中被拒绝。还没有听说要恢复它。
猜你喜欢
  • 2016-07-05
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 2022-10-16
  • 1970-01-01
  • 2013-10-01
  • 1970-01-01
  • 2011-06-28
相关资源
最近更新 更多