【问题标题】:Specializing function template for templated derived class模板化派生类的专用函数模板
【发布时间】:2014-02-04 07:44:03
【问题描述】:

我基本上有一个 std::integral_constant 的模拟版本,其中包含一个变量,我想为这些从 Base<T> 派生的类专门化一个函数模板,如下所示:

template<class T> struct Base{
  typedef T type;
  T t;
};

template<class T> struct A : Base<T>{
  static constexpr T value = 1;
};
template<class T> struct B : Base<T>{
  static constexpr T value = 2;
};

struct Unrelated{};

// etc.

template<class T> void foo(T t){
  //I would like to specialize foo for A and B and have a version for other types
}


int main(){
  foo(A<float>());//do something special based on value fields of A and B
  foo(B<float>());
  foo(Unrelated()); //do some default behavior
}

以下是主要问题:

  • 我不能将 value 包含为模板,因为我期望 T = doublefloat 或其他一些非整数类型(否则我只会扩展 std::integral_constant
  • 我不能像 std::is_base&lt;Base&lt;T::type&gt;,T&gt; 那样干净地使用 std::is_base
  • 执行foo(Base&lt;T&gt;&amp;) 不会让我看到value,我不想求助于虚拟value() 函数(或反射)。
  • 显然我希望避免为每个派生类专门设置 foo。

我认为答案在于使用is_base,但无论我如何尝试使用它,我都无法让它工作。我错过了更简单的方法吗?

【问题讨论】:

  • 当然,你有一两个错字。 template&lt;class T&gt; struct A : Base{ 应该是 template&lt;class T&gt; struct A : Base &lt;T&gt;{。这是你的全部问题吗?
  • +1 用于清楚地表达首先 what 你想做什么,然后是 how 你想做什么,最后问如何你应该做你想做的事。
  • 另外,请阅读this
  • 我确定我在粘贴之前已经抓住了它,谢谢!但我很确定我需要专攻,因为我不想重载 Base 的每个子类型,也不能重载 Base&.

标签: c++ templates c++11 template-specialization


【解决方案1】:

以下应该有效:

template<typename,typename = void>
struct IsBase
  : std::false_type {};

template<typename T>
struct IsBase<T, typename std::enable_if<
                   std::is_base_of<Base<typename T::type>,T>::value
                 >::type>
  : std::true_type {};

template<class T>
typename std::enable_if<IsBase<T>::value>::type foo(T t){
    // use T::value
}

template<class T>
typename std::enable_if<!IsBase<T>::value>::type foo(T t){
    // general case
}

Live example

【讨论】:

  • 如果我做foo&lt;Unrelated&gt;()(至少在g++4.6上对我来说)将不起作用,即使它没有在typename T::type.失败的问题就像我说的那样,我实际上做了同样的事情,但无法按照我的意愿充分发挥作用。
  • @user783920 foo&lt;Unrelated&gt;() 不提供参数,但foo(如您定义的那样)需要参数t。如果您没有正确描述您的问题,我认为我无能为力。
  • 我已经删除了模板,但现在它可以工作了。我想我忘了保存什么的,抱歉。
猜你喜欢
  • 2014-09-23
  • 1970-01-01
  • 2010-12-28
  • 1970-01-01
  • 1970-01-01
  • 2016-07-02
  • 2014-10-01
  • 1970-01-01
  • 2018-10-16
相关资源
最近更新 更多