4

I can deal with porting platform dependent functions. I have a problem that the compilers I tried on Linux (clang and g++) do not accept the following code, while the msvc++ compiler does:

template <class T>
class Base {
protected:
    T Value;
};

template <class T>
class Derived : public Base<T> {
public:
    void setValue(const T& inValue){
        Value = inValue;
    }
};

int main(int argc, char const *argv[])
{
    Derived<int> tmp;
    tmp.setValue(0);
    return 0;
}

g++ error:

main.cpp: In member function ‘void Derived<T>::setValue(const T&)’:
main.cpp:11:3: error: ‘Value’ was not declared in this scope

I believe this due to the use of a non-dependent name (Value) in the second class. More information.

The problem is that I have a very large code base, in which this type of code is used very often. I understand that it is wrong when looking at the standard. However it is very convenient not having to write this-> or Base<T>:: in front of every use of Value. Even writing using Base<T>::Value; at the start of the derived class is problematic when you use ~20 members of the base class.

So my question is: are there compilers for Linux that allow this kind of code (with or without extra compiler switches)? Or are there small modifications that will allow this code to compile on Linux?

user362382
  • 3,954
  • 2
  • 17
  • 11
  • 1
    I'd consider `this->` infront of member access to be a small modification, tbh. – Xeo Oct 30 '12 at 14:03

5 Answers5

6

You have to say this->Value or Base<T>::Value, because Value is a dependent name. Alter­natively, add using Base<T>::Value; to your derived class definition. There's no way around this.

The Microsoft compiler was simply sub-standard, and it is your misfortune to have coded to a vendor's style and not to the published C++ standard, I'm afraid.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
2

You can add using statements to your derived class. That may just complicate your life:

template <class T>
class Derived : public Base<T> {
    using Base<T>::Value;
public:
    void setValue(const T& inValue){
        Value = inValue;
    }
};
Ben
  • 193
  • 5
1

To answer your question, yes, there is a compiler for Linux that accepts this code: Intel C++. Tested with version 13.0.0.079. You need to use the -fpermissive compiler flag.

I agree with Kerrek SB though; it's best to fix the code. There's no guarantee that Intel C++ will keep the current behavior. There's even no guarantee that Microsoft's compiler will keep it.

Nikos C.
  • 50,738
  • 9
  • 71
  • 96
1

Clang supports several compatibility flags for MSVC.

I believe specifically that -fdelayed-template-parsing is the one you are looking for.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
0

if you want to use Value in Derived. you can redefine it like the following, so you avoid this-> or Base::

using Base<T>::Value

just once inside the definiton of Derived and you should be able to use it everywhere

Edit1: Ok sorry, I removed the first part about class and typename keywords

Moataz Elmasry
  • 2,509
  • 4
  • 27
  • 37
  • [`class` and `typname` for template type parameters are synonyms.](http://stackoverflow.com/q/2023977/500104) – Xeo Oct 30 '12 at 14:07