【问题标题】:template specialization of template class模板类的模板特化
【发布时间】:2009-08-23 12:32:09
【问题描述】:

我想专门研究以下成员函数:

class foo {
    template<typename T>
    T get() const;
};

到其他类bar 也依赖于模板。

例如,我希望bar 成为带有一些模板参数的std::pair,类似这样:

template<>
std::pair<T1,T2> foo::get() const
{
    T1 x=...;
    T2 y=...;
    return std::pair<T1,T2>(x,y);
}

其中 T1 和 T2 也是模板。如何才能做到这一点?据我所知应该是 可能。

所以现在我可以打电话了:

some_foo.get<std::pair<int,double> >();

完整/最终答案:

template<typename T> struct traits;
class foo {
    template<typename T>
    T get() const
    {
       return traits<T>::get(*this); 
    }
};

template<typename T>
struct traits {
    static T get(foo &f)
    {
        return f.get<T>();
    }
};

template<typename T1,typename T2>
struct traits<std::pair<T1,T2> > {
        static std::pair<T1,T2> get(foo &f)
        {
                T1 x=...;
                T2 y=...;
                return std::make_pair(x,y);
        }
};

【问题讨论】:

  • 不清楚你的意思。您是否想要在 T1 和 T2 是模板时应用的专业化?或者当它们是一些特定的模板时?或者当它们是模板,并且它们的参数是某些特定类型时?
  • 我的意思是,我想将我的函数专门用于需要一些模板参数的其他特定类型(如 std::pair)。

标签: c++ templates specialization


【解决方案1】:

您不能部分专门化函数模板,抱歉,这是规则。您可以执行以下操作:

class foo {
   ...
};


template<typename T>
struct getter {
  static T get(const foo& some_foo);
};

template<typename T1, typename T2>
struct getter< std::pair<T1, T2> > {
static std::pair<T1, T2> get(const foo& some_foo) {
    T1 t1 = ...;
    T2 t2 = ...;
    return std::make_pair(t1, t2);
};

然后像这样称呼它

getter<std::pair<int, double> >::get(some_foo);

虽然。如果 get 确实需要成为成员函数,您可能不得不对 friendship 或可见性进行一些处理。

详细说明 sbi 的建议:

class foo {
   ...
   template<typename T>
   T get() const;
};

template<typename T>
T foo::get() const
{
  return getter<T>::get(*this);
  /*            ^-- specialization happens here */
}

现在你又能说出来了

std::pair<int,double> p = some_foo.get<std::pair<int, double> >();

【讨论】:

  • 你可以。但是,使getter 成为类的(可能是private)成员,并通过普通成员函数模板调用它。这样,您班级的用户就不必关心这种机制。
【解决方案2】:

你需要为pair重载你的成员函数,比如在

template <T, V> std::pair<T, V> foo::get()

在一般情况下,您需要能够消除各种重载之间的歧义。在这种情况下,消除歧义很容易,因为 pair 在 2 种类型上模板化,而原始成员仅在 T 上模板化。

如果你需要一个专门化的实例,例如 std::vector,即具有单个参数模板的容器,你必须小心,因为如果你想实例化编译器可能会混淆它模板特化,其中模板 T 是 std::vector 或重载的特化,

template <T> std::<vector <T> foo::get() const 

您建议的语法无法工作,因为您完全专门化了成员函数,

template &lt;&gt;,

但您忽略了两种未指定的类型,T1 和 T2。

【讨论】:

  • 这不起作用:“std::pair&lt;_T1, _T2&gt; foo::get() 的原型与 foo 类中的任何一个都不匹配;候选者是:模板 T foo::get()”
  • 您必须在 foo 类中声明 template &lt;typename T, typename V &gt; std::pair&lt;T, V&gt; get() const;,然后将其命名为:std::pair&lt;int, int&gt; p_int = f.get&lt;int, int &gt;();
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-10
  • 1970-01-01
  • 2018-11-26
  • 2015-11-14
  • 1970-01-01
相关资源
最近更新 更多