Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ template specialisation & inheritance

I have a following piece of code, which should declare base struct and then declare template struct inheriting from it. Then the struct is partially specilised.

#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;
}

When I compile it in Visual Studio 2015, everything compiles just fine and works as expected. However when I compile with GCC 5.2.1 or clang 3.6 I get following error:

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;

What's wrong? However when I refer m_pair as Parent<A, B>::m_pair it works in GCC and clang.

What is the correct way to define specilised template clasess (with specilised methods), which share common methods?

like image 878
yaqwsx Avatar asked Mar 21 '26 05:03

yaqwsx


1 Answers

Since the base class is dependent on template parameters, the base members are not examined during unqualified name lookup.

Fortunately the fix is easy: just prefix the base member accesses with this->:

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

This will look in the base class, so the member will be found.

The unqualified lookup works in MSVC because that compiler is non-conformant in many aspects of its template implementation.

like image 198
TartanLlama Avatar answered Mar 23 '26 18:03

TartanLlama