从内部类调用模板函数

时间:2017-11-25 15:39:46

标签: c++ c++14

我有一个这样的类来根据类型调用函数。我尝试编译它,但有错误错误C2059语法错误:'template'

class A
{
  call_1()
{
  B<type> b;
  b.template say(i);
}

template<class T>
    struct B
    {
        template <typename T, typename I>
        T say(I i) {
            return word;
        }
    };
    template<>
    struct B<void>
    {
        template <typename T, typename I>
        void say(I i) {
            /**/
        }
    };
}

我做错了什么?

1 个答案:

答案 0 :(得分:1)

首先,让我们将您的示例重写为可读且更接近可编译的内容,我们还在say()中打印“1”或“2”以了解调用哪个函数:

#include <iostream>
using type = int;

class A {
    void call_1() {
        B<type> b;
        int i = 0;
        b.template say(i);
    }

    template<class T>
    struct B
    {
        template <typename T, typename I>
        T say(I i) {
            std::cout << "1\n";
            return T();
        }
    };

    template<>
    struct B<void>
    {
        template <typename T, typename I>
        void say(I i) {
            std::cout << "2\n";
        }
    };
};

好的,首先,您尝试在B内专门化A。这是不允许的,所以不要将它移到A之外:

using type = int;

class A {
    void call_1() {
        B<type> b;
        int i = 0;
        b.template say(i);
    }

    template<class T>
    struct B
    {
        template <typename T, typename I>
        T say(I i) {
            std::cout << "1\n";
            return T();
        }
    };
};

template<>
struct A::B<void>
{
    template <typename T, typename I>
    void say(I i) {
        std::cout << "2\n";
    }
};

接下来,您在TB中使用相同的模板参数(say())。您无需重复T,所以我们将其删除:

using type = int;

class A {
    void call_1() {
        B<type> b;
        int i = 0;
        b.template say(i);
    }

    template<class T>
    struct B
    {
        template <typename I>
        T say(I i) {
            std::cout << "1\n";
            return T();
        }
    };
};

template<>
struct A::B<void>
{
    template <typename I>
    void say(I i) {
        std::cout << "2\n";
    }
};

最后,在call_1()的专业化之前无法定义A::B,因此我们也需要将其移到外面:

using type = int;

class A {
    void call_1();

    template<class T>
    struct B
    {
        template <typename I>
        T say(I i) {
            std::cout << "1\n";
            return T();
        }
    };
};

template<>
struct A::B<void>
{
    template <typename I>
    void say(I i) {
        std::cout << "2\n";
    }
};

void A::call_1() {
    B<type> b;
    int i = 0;
    b.template say(i);
}

现在应该编译并执行您想要的操作。致电call_1()将打印1。如果您将typeint更改为void

using type = void;

它会打印2