4

Can someone please tell me why the following code works perfectly in Visual Studio 2010 but fails to compile in gcc 5.3 despite that it seems there is nothing wrong with it? I have already done some googling but had no luck in finding a clear and standard way of describing template class inheritance.

#include <iostream>
#include <string>

namespace foobar
{
    template <typename Char_Type = char>
    class basic_foo
    {
    public:
        inline basic_foo(){}
        virtual ~basic_foo(){}

        typedef std::basic_string< Char_Type > str_foo;
        enum { fooEnum = 100 };
    };

    template <typename Char_Type = char>
    class basic_bar :private basic_foo <Char_Type>
    {
    public:
        basic_bar(){}
        ~basic_bar(){}

        str_foo bar1()
        {
            int i = fooEnum;
            return str_foo("test succeeded\n");
        }
    };
}

typedef foobar::basic_bar<> bar2;

int main()
{
    bar2 bar;
    std::cout << bar.bar1();
    return 0;
}

in visual studio, it results in:

test succeeded

but in gcc, it says:

main.cpp|24|error: unknown type name 'str_foo'
main.cpp|26|error: use of undeclared identifier 'fooEnum'
main.cpp|27|error: use of undeclared identifier 'str_foo'
||=== Build failed: 3 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
polfosol ఠ_ఠ
  • 1,470
  • 22
  • 33

1 Answers1

6

Problem is in two-phase lookup, which is implemented in gcc/clang and not implemented in VS.

Your code should use typename and this where needed by standard:

template <typename Char_Type = char>
class basic_bar :private basic_foo <Char_Type>
{
public:
    basic_bar(){}
    ~basic_bar(){}

    typename basic_foo<Char_Type>::str_foo bar1()
    {
        int i = this->fooEnum;
        return typename basic_foo<Char_Type>::str_foo("test succeeded\n");
    }
};

live example

You can read Where and why do I have to put the "template" and "typename" keywords? and Two phase lookup - explanation needed

Community
  • 1
  • 1
ForEveR
  • 52,568
  • 2
  • 101
  • 125