Quantcast
Channel: Intel® C++ Compiler
Viewing all articles
Browse latest Browse all 1616

Compiler bug: error : nontype "" is not a template

$
0
0

This code:

template <class... Types>
struct TypeList
{
	template <class... AppendTypes>
	using Append = TypeList<Types..., AppendTypes...>;
};

template <class Types>
struct TestStruct
{
	// this works
	template <class T>
	TestStruct<Types::Append<T>> add() { return TestStruct<Types::Append<T>>(); }

	// this doesn't
	template <class... T>
	TestStruct<Types::Append<T...>> add() { return TestStruct<Types::Append<T...>>(); }
};

int main()
{
	TestStruct<TypeList<>> foo;
	auto x = foo.add<int, float>().add<char>();
}

produces the following error:

1>ConsoleTests.cpp(17): error : nontype "Types::Append" is not a template
1>    	TestStruct<Types::Append<T...>> add() { return TestStruct<Types::Append<T...>>(); }
1>    	                                                                 ^
1>  
1>ConsoleTests.cpp(23): error : template instantiation resulted in unexpected function type of "TestStruct<TypeList<int, float>> ()" (the meaning of a name may have changed since the template declaration -- the type of the template is "TestStruct<TypeList<T>> ()")
1>    	auto x = foo.add<int, float>().add<char>();
1>    	                              ^
1>            detected during instantiation of "TestStruct<Types>::add [with Types=TypeList<>]" based on template arguments <int, float> at line 23
1>  
1>ConsoleTests.cpp(23): error : type name is not allowed
1>    	auto x = foo.add<int, float>().add<char>();
1>    	                                   ^
1>  
1>ConsoleTests.cpp(23): error : expected an expression
1>    	auto x = foo.add<int, float>().add<char>();

I've tried the following workaround:

template <class... Types>
struct TypeList
{
	template <class... AppendTypes>
	using Append = TypeList<Types..., AppendTypes...>;
};

template <class TypeList, class... Types>
struct AppendHelper;

template <class... TypeListTypes, class... Types>
struct AppendHelper<TypeList<TypeListTypes...>, Types...>
{
    using TypeList = TypeList<TypeListTypes..., Types...>;
};

template <class TypeList, class... Types>
using Append = typename AppendHelper<TypeList, Types...>::TypeList;

template <class Types>
struct TestStruct
{
    template <class... T>
    TestStruct<Append<Types, T...>> add() { return TestStruct<Append<Types, T...>>(); }
};

int main()
{
    TestStruct<TypeList<>> foo;
    auto x = foo.add<int, float>().add<char>();
}

this fixes the first error, but the others remain:

1>ConsoleTests.cpp(30): error : template instantiation resulted in unexpected function type of "TestStruct<Append<TypeList<>, int, float>> ()" (the meaning of a name may have changed since the template declaration -- the type of the template is "TestStruct<AppendHelper<TypeList<>, T>::TypeList> ()")
1>        auto x = foo.add<int, float>().add<char>();
1>                                      ^
1>            detected during instantiation of "TestStruct<Types>::add [with Types=TypeList<>]" based on template arguments <int, float> at line 30
1>  
1>ConsoleTests.cpp(30): error : type name is not allowed
1>        auto x = foo.add<int, float>().add<char>();
1>                                           ^
1>  
1>ConsoleTests.cpp(30): error : expected an expression
1>        auto x = foo.add<int, float>().add<char>();

In my opinion both versions are legal C++11 code.

Best regards,
Manuel Pöter


Viewing all articles
Browse latest Browse all 1616

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>