1

I am trying to touch C++17 features and I have selected clang. Here is simplified example of my code that could not be compiled via clang:

#include <iostream>
#include <limits>

template<
    typename T,
    template<typename T_> typename Final>
class Base
{
public:
    decltype(auto) Foo() const noexcept
    {
        using TFinal = Final<T>;
        auto& _this = static_cast<const TFinal&>(*this);
        return _this.Bar<true>();
    }
};

template<typename T>
class Derived :
    public Base<T, ::Derived>
{
public:
    template<bool min>
    T Bar() const noexcept
    {
        return min ?
            std::numeric_limits<T>::lowest() :
            std::numeric_limits<T>::max();
    }
};

int main()
{
    Derived<int> instance;
    auto result = instance.Foo();
    std::cout << result << std::endl;
    return 0;
}

It fails here:

return _this.Bar<true>();

and error message is:

main.cpp:14:32: error: expected expression
        return _this.Bar<true>();
                               ^
main.cpp:35:10: error: variable has incomplete type 'void'
    auto result = instance.Foo();
         ^    

Here is how I am compiling it:

clang++-5.0 main.cpp -std=c++17

Some additional info. Visual Studio 17 with latest language version can eat this. When bar function is not template, everything is ok...

Any suggestions what is wrong here?

Barry
  • 286,269
  • 29
  • 621
  • 977

1 Answers1

5

Should be

return _this.template Bar<true>();

In your case _this has dependent type. To refer to its member templates you have to use the keyword template explicitly.

Where and why do I have to put the "template" and "typename" keywords?

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765