2016-09-23 104 views
0

编译以下代码时遇到此错误。 在做了一些研究并在不同情况下阅读了类似的错误之后,我想出了我需要的解决方案。 但我没有完全明白错误和修复的原因。模板继承:没有参数取决于模板参数

template <typename T> 
class TestA { 
    int a; 
    T temp; 

protected: 
    int b; 

public: 
    int c; 

    TestA(T te): a{10}, b{20}, c{30}, temp{te} {} 

    int geta(){ return a; } 
    int getb(){ return b; } 
    int getc(){ return c; } 
}; 

template <typename T> 
class TestB { 
    int atb; 
    T tempb; 

protected: 
    int btb; 

public: 
    int ctb; 

    TestB(T te) atb{10}, btb{20}, ctb{30}, tempb{te} {} 
}; 

template <typename T> 
class TestInh : public TestA<T>, public TestB<T> { 
    int aa; 
    T temptemp; 

protected: 
    int bb; 
    int b; 

public: 
    int cc; 

    TestInh(T te) : TestA<T>{te}, TestB<T>{te}, bb{10000}, b{-1000} {} 

    int get_total() { 
     // The error happens here! 
     return geta(); 
    } 
}; 

int main(int argc, char const *argv[]) { 
    char text = 'a'; 
    TestInh<char> test(text); 

    //std::cout << test.geta() << std::endl; 
    std::cout << test.get_total() << std::endl; 
    //std::cout << test.c << std::endl; 
    return 0; 
} 

当编译这段代码,我得到这个错误:

testtemplate.cc: In member function ‘int TestInh<T>::get_total()’: 
testtemplate.cc:54:32: error: there are no arguments to ‘geta’ that depend on a template parameter, so a declaration of ‘geta’ must be available [-fpermissive] 
int get_total() {return geta();} 
          ^
testtemplate.cc:54:32: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated) 

它是通过调用this->geta(),而不是仅仅geta()解决,但我不完全理解为什么这不能由编译器来解决。

有人能解释我为什么吗?

+0

它与VS2015 – GpG

+0

编译@Gpg MSVC是错误的。不要依赖它来包含关键字'template'的所有内容。 –

回答

4

当扩展一个依赖于模板参数的类时,this种类变成了依赖名称。

问题是,在执行两阶段名称查找时,编译器无法知道他在哪里可以找到函数geta。他不知道它来自父母。因为模板专业化是一件事情,所以TestA<int>TestA<double>可能是两个完全不同的clas swith不同的功能和成员。

随着this关键字的添加,编译器知道geta必须是成员函数。

没有它,它可能是成员函数或非成员函数,或者TestB的成员函数。

想象一下模板代码,它将根据某些模板条件调用getaTestAgetaTestB。哎哟。编译器希望确保代码对于每个模板实例都是一致的。

说,以该函数作为一个成员函数存在的编译器的另一种方法是添加using语句:

template <typename T> 
struct TestInh : TestA<T>, TestB<T> { 
    // some code... 

    using TestA<T>::geta; 

    int get_total() { 
     // works! With the above using statement, 
     // the compiler knows that 'geta()' is 
     // a member function of TestA<T>! 
     return geta(); 
    } 
}; 
+0

谢谢!这是我正在寻找的。 – luisremis