特定成员的模板专业化? [英] Template specialization of particular members?

查看:126
本文介绍了特定成员的模板专业化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以专门化模板类的特定成员?例如:

Is it possible to specialize particular members of a template class? Something like:

template <typename T,bool B>
struct X
{
    void Specialized();
};

template <typename T>
void X<T,true>::Specialized()
{
    ...
}

template <typename T>
void X<T,false>::Specialized()
{
    ...
}

当然,此代码无效。

推荐答案

它显式地通过提供所有模板参数。不允许类模板的成员函数的部分专门化。

You can only specialize it explicitly by providing all template arguments. No partial specialization for member functions of class templates is allowed.

template <typename T,bool B>
struct X
{
    void Specialized();
};

// works
template <>
void X<int,true>::Specialized()
{
    ...
}

一个解决方法是引入重载函数,它们仍然在同一个类中,因此它们对成员变量,函数和东西都有相同的访问权限。

A work around is to introduce overloaded functions, which have the benefit of still being in the same class, and so they have the same access to member variables, functions and stuffs

// "maps" a bool value to a struct type
template<bool B> struct i2t { };

template <typename T,bool B>
struct X
{
    void Specialized() { SpecializedImpl(i2t<B>()); }

private:
    void SpecializedImpl(i2t<true>) { 
      // ...
    }

    void SpecializedImpl(i2t<false>) { 
      // ...
    }
};

请注意,通过传递给重载函数并将模板参数推入函数参数,任意专门化您的函数,并且还可以根据需要对它们进行模板化。另一个常见的技术是推迟到单独定义的类模板

Note that by passing along to the overloaded functions and pushing the template parameters into a function parameter, you may arbitrary "specialize" your functions, and may also templatize them as needed. Another common technique is to defer to a class template defined separately

template<typename T, bool B>
struct SpecializedImpl;

template<typename T>
struct SpecializedImpl<T, true> {
  static void call() { 
    // ...
  }
};

template<typename T>
struct SpecializedImpl<T, false> {
  static void call() { 
    // ...
  }
};

template <typename T,bool B>
struct X
{
    void Specialized() { SpecializedImpl<T, B>::call(); }
};



我发现通常需要更多的代码,我发现函数重载更容易处理,推迟到类模板方式。到底是一个味道的问题。在这种情况下,你可以将 X 中的其他模板也作为嵌套模板 - 在其他情况下,你明确专门化而不是部分,那么你不能因为你可以只在命名空间范围,而不是在类范围中放置显式专门化。

I find that usually requires more code and i find the function overload easier to handle, while others prefer the defer to class template way. In the end it's a matter of taste. In this case, you could have put that other template inside X too as a nested template - in other cases where you explicitly specialize instead of only partially, then you can't do that, because you can place explicit specializations only at namespace scope, not into class scope.

您还可以创建这样的 SpecializedImpl 模板,仅仅是为了函数重载的目的code> i2t of before),因为下面的变体证明了第一个参数变量也是如此(所以你可以用其他类型调用它 - 不仅仅是当前实例化的模板参数) p>

You could also create such a SpecializedImpl template just for purpose of function overloading (it then works similar to our i2t of before), as the following variant demonstrates which leaves the first parameter variable too (so you may call it with other types - not just with the current instantiation's template parameters)

template <typename T,bool B>
struct X
{
private:
    // maps a type and non-type parameter to a struct type
    template<typename T, bool B>
    struct SpecializedImpl { };

public:
    void Specialized() { Specialized(SpecializedImpl<T, B>()); }

private:
    template<typename U>
    void Specialized(SpecializedImpl<U, true>) {
      // ...
    }

    template<typename U>
    void Specialized(SpecializedImpl<U, false>) {
      // ...
    }
};



我认为有时候,推迟到另一个模板是更好的(当涉及到诸如数组和指针,重载可能很棘手,只是转发到类模板对我来说更容易),有时只是在模板内的重载更好 - 特别是如果你真的转发函数参数,如果你触摸类的成员变量。

I think sometimes, deferring to another template is better (when it comes to such cases as arrays and pointers, overloading can tricky and just forwarding to a class template has been easier for me then), and sometimes just overloading within the template is better - especially if you really forward function arguments and if you touch the classes' member variables.

这篇关于特定成员的模板专业化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆