2015-12-03 60 views
3

我有一段代码,它应该声明基本结构,然后声明模板结构继承它。然后结构部分specilised。C++模板特化和继承

#include <utility> 
#include <iostream> 

template<class A, class B> 
struct Parent { 
    std::pair<A, B> m_pair; 
    void print() { 
     std::cout << m_pair.first << ", " << m_pair.second << "\n"; 
    } 
}; 

template <class A, class B> 
struct Some : public Parent<A, B> { 
    Some(A a, B b) : Parent<A, B>({ {a, b} }) {} 
    void add() { 
     m_pair.first += m_pair.second; 
    } 
}; 

template <class B> 
struct Some<B, float> : public Parent<B, float> { 
    Some(B a, float b) : Parent<B, float>({ {a, b} }) {} 
    void add() { 
     m_pair.first -= m_pair.second; 
    } 
}; 

int main() { 
    Some<int, float> s(4, 42); 
    s.add(); 
    s.print(); 
    return 0; 
} 

当我在Visual Studio 2015中编译它时,一切都编译得很好,并按预期工作。但是,当我编译与GCC 5.2.1或铿锵3.6我得到以下错误:

untitled.cpp: In member function ‘void Some<A, B>::add()’: 
untitled.cpp:17:9: error: ‘m_pair’ was not declared in this scope 
     m_pair.first += m_pair.second; 
     ^
untitled.cpp: In member function ‘void Some<B, float>::add()’: 
untitled.cpp:24:9: error: ‘m_pair’ was not declared in this scope 
     m_pair.first += m_pair.second; 

怎么了?但是,当我将m_pair指定为Parent<A, B>::m_pair时,它在GCC和叮当中起作用。

什么是正确的方式来定义specilised模板clasess(与specilised方法),共享共同的方法?

回答

5

由于基类依赖于模板参数,所以在非限定名称查找期间不会检查基础成员。

幸运的修复很简单:只需前缀基础构件与this->访问:

this->m_pair.first += this->m_pair.second; 
this->m_pair.first -= this->m_pair.second; 

看在基类,所以该成员将被发现。

无条件查找在MSVC中起作用,因为该编译器在其模板实现的很多方面都不符合要求。