模板类的模板特化

发布于 2024-08-02 20:38:29 字数 1126 浏览 5 评论 0原文

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

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);
        }
};

I want to specialize following member function:

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

To other class bar that depends on templates as well.

For example, I would like bar to be std::pair with some template parameters, something like that:

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

Where T1 and T2 are templates as well. How can this be done? As far as I know it should be
possible.

So now I can call:

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

The full/final answer:

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);
        }
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜血缘 2024-08-09 20:38:29

您不能部分专门化函数模板,抱歉,但这些是规则。你可以做类似的事情:

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 或可见性进行一些处理。

详细说明履行机构的建议:

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> >();

You can't partially specialize function templates, sorry but those are the rules. You can do something like:

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);
};

and then call it like

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

though. You may have to do some messing around with friendship or visibility if get really needed to be a member function.

To elaborate on sbi's suggestion:

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

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

And now you're back to being able to say

std::pair<int,double> p = some_foo.get<std::pair<int, double> >();
随心而道 2024-08-09 20:38:29

您需要成对重载您的成员函数,就像在

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

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

相反,如果您需要专门化,例如 std::vector,即具有单个参数模板的容器,则必须小心,因为如果您希望实例化模板专门化,编译器可能会感到困惑。其中模板 T 是 std::vector 或重载的专门化,

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

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

template <>

但您遗漏了两个未指定的类型,T1 和 T2。

You need to overload your member function for pair, like in

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

In the general case you will need to be able to disambiguate between the various overloads. In the case disambiguation is easy because pair is templated on 2 types while the original member was templated on T only.

If instead you needed a specialization for, e.g., std::vector, that is for a container with a single parameter template, you have to be careful since given it can be confusing for the compiler to understand if you wish to instantiate the template specialization where the template T is std::vector or the specialization for the overload,

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

Your proposed syntax cannot work since you are completely specializing the member function,

template <>,

but you are leaving out two unspecified types, T1 and T2.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文