如何为另一个模板类型重载模板类方法?

时间:2016-10-20 09:13:11

标签: c++ templates

在不使用Boost的情况下,C ++ 03中的标准方法是:

  1. 重载模板类方法,其中模板类型仅出现在方法的返回值中,或
  2. 专门为另一个模板类型设置模板类方法。
  3. 换句话说,如何才能使其发挥作用:

    template <typename T, int N> struct Vector { T x[N]; };
    
    struct Sampler
    {
        template <typename T>
        T next() {
            // Do some work and return a value of type T.
            return T();
        }
    
        template <typename T, int N>
        Vector<T, N> next() {
            // Do some different work and return a value of type Vector<T, N>.
            return Vector<T, N>();
        }
    };
    
    int main() {
        Sampler sampler;
        sampler.next<double>();
        sampler.next<Vector<float, 2> >();
        return 0;
    }
    

    如上所述,next()的两个用法都调用了第一种方法,而我希望第二种方法用于调用第二种方法。

2 个答案:

答案 0 :(得分:3)

您似乎要求对模板功能进行部分专业化。这不是语言,但你可以使用标签调度或类模板来模拟它。以下是标签调度的示例:

template <typename T> struct tag{};
struct Sampler
{    
    template <typename T>
    T next() {
        return next(tag<T>());   
    }

private:
    template <typename T>
    T next(tag<T>) {
        return T();
    }

    template <typename T, int N>
    Vector<T, N> next(tag<Vector<T,N> >) {
        return Vector<T, N>();
    }
};

然后你就这样使用它:

sampler.next<double>();
sampler.next<Vector<double,2> >();

Live demo

请注意,在C ++ 11之前的第二行中,最后> >个令牌之间需要一个空格。

答案 1 :(得分:2)

您可以使用辅助结构:

template<typename T>
struct SamplerHelper
{
    T operator()() const 
    {
        std::cout << "T\n";
        return T();
    }
};

template<typename T, int N>
struct SamplerHelper<Vector<T, N> >
{
    Vector<T, N> operator()() const 
    {
        std::cout << "vec\n";
        return Vector<T, N>();
    }
};

struct Sampler
{
    template <typename T>
    T next() {
        return SamplerHelper<T>()();
    }
};

A working example is available on wandbox