0

The best I can determine is that symbols defined in the parent class are no longer carried into the child class by default. This is counter to the way I've always believed C++ to work.

template<typename T>
class Parent
{
public:
    typedef T* iterator;
};

template<typename T>
class Child : public Parent < T >
{
public:
    //using iterator = Parent<T>::iterator; // this fixes error C3646 and error C2059

    iterator begin(void)
    {
        return nullptr;
    }
};

1>Test1.cpp(14,1): error C3646:  'begin': unknown override specifier
1>Test1.cpp(18): message :  see reference to class template instantiation 'Child<T>' being compiled
1>Test1.cpp(14,16): error C2059:  syntax error: '('
1>Test1.cpp(15,1): error C2334:  unexpected token(s) preceding '{'; skipping apparent function body

This started happening when I changed the file settings to use C++14 or C++17, prior to that it was OK. There appears to be no way to restore the prior behavior, even selecting "Default" generates the errors. It still works fine in Visual Studio 2013.

enter image description here

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • related/dupe: https://stackoverflow.com/questions/1120833/derived-template-class-access-to-base-class-member-data This is correct behavior, MSVS just didn't enforce it. – NathanOliver Sep 25 '19 at 17:53
  • @NathanOliver so you're saying this was a bug in the MS compiler for many years that was just finally fixed? – Mark Ransom Sep 25 '19 at 18:02
  • Note that you are compiling using [(standard) `Conformance mode`](https://learn.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view=vs-2019) introduced in VS2017. They even have "How to fix your code" section in docs listing fixes for breaking changes to address such questions. – user7860670 Sep 25 '19 at 18:02
  • @MarkRansom Yes. MSVS is known to have done this in several places. Like allowing non-const lvalue references to bind to temporaries. That was around for many years and many versions – NathanOliver Sep 25 '19 at 18:04
  • 1
    @VTT that was accidental because I created a new project for testing. The code where I originally encountered this error did not have that option set. – Mark Ransom Sep 25 '19 at 18:08
  • This is getting muddled. The conformance mode setting is the key. With it set to Yes it will reject the code even without selecting C++14. Use No to get old code to compile that relied on "nobody will pay for a compiler when it breaks the code" mode. – Hans Passant Sep 25 '19 at 18:25
  • @HansPassant I agree it's muddled. The project where I first encountered this error **did** have the option set to "No", so there's obviously more to it. – Mark Ransom Sep 25 '19 at 18:36
  • Well, there is. This setting can have different values for different configurations and platforms. So if you set it to No for Debug (as you did in the screenshot) but forgot for Release then you'll have a problem. Not a great idea. – Hans Passant Sep 25 '19 at 18:40

0 Answers0