Template does not compile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Count sequentially equal elements for both arrays from the start:
namespace Detail
{
// Not equal, stop and give result:
	template<class Type, class CheckedEquals, Type FirstValue, Type SecondValue, class FirstArray, class SecondArray>
	struct TCompareStaticArraysSequentially
	{
		using Equals = CheckedEquals;
	};
// Equal, continue:
	template<class Type, class CheckedEquals, Type Value, class FirstArray, class SecondArray>
	struct TCompareStaticArraysSequentially<Type, CheckedEquals, Value, Value, FirstArray, SecondArray>
	{
		struct Equals : TCompareStaticArraysSequentially<Type, class CheckedEquals::template PushBack<Value>,
			FirstArray::PopFront::Front, SecondArray::PopFront::Front,
			class FirstArray::PopFront, class SecondArray::PopFront>::Equals {}; // WORKS
		using Equals = TCompareStaticArraysSequentially<Type, class CheckedEquals::template PushBack<Value>,
			FirstArray::PopFront::Front, SecondArray::PopFront::Front,
			class FirstArray::PopFront, class SecondArray::PopFront>::Equals; // DOES NOT WORK
	};
// Come to an end of one of the arrays:
	template<class Type, class CheckedEquals, Type FirstValue, Type SecondValue, class Array>
	struct TCompareStaticArraysSequentially<Type, CheckedEquals, FirstValue, SecondValue, TEmptyStaticArray<Type>, Array>
	{
		using Equals = CheckedEquals;
	};
	template<class Type, class CheckedEquals, Type FirstValue, Type SecondValue, class Array>
	struct TCompareStaticArraysSequentially<Type, CheckedEquals, FirstValue, SecondValue, Array, TEmptyStaticArray<Type>>
	{
		using Equals = CheckedEquals;
	};
}


As you see the comments, one through the struct works (not nice one maybe), another with using doesn't.

Why?

Edit:

And further, maybe it will help, is same:

1
2
3
4
5
6
template<class Type, class FirstArray, class SecondArray>
//using TCompareStaticArraysSequentially = Detail::TCompareStaticArraysSequentially<Type, TEmptyStaticArray<Type>,
	//FirstArray::Front, SecondArray::Front, FirstArray, SecondArray>::Equals;
// DOES NOT WORK
struct TCompareStaticArraysSequentially : Detail::TCompareStaticArraysSequentially<Type, TEmptyStaticArray<Type>,
	FirstArray::Front, SecondArray::Front, FirstArray, SecondArray>::Equals {};

Last edited on
Disambiguate that the dependent name is the name of a type with the typename disambiguator, and it (the template definition; haven't checked the template instantiation) compiles cleanly with both clang++ and the Microsoft compiler.
The GNU compiler appears to choke on this, though.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
template < typename T > struct TEmptyStaticArray {} ;

namespace Detail
{
// Not equal, stop and give result:
	template<class Type, class CheckedEquals, Type FirstValue, Type SecondValue, class FirstArray, class SecondArray>
	struct TCompareStaticArraysSequentially
	{
		using Equals = CheckedEquals;
	};
// Equal, continue:
	template<class Type, class CheckedEquals, Type Value, class FirstArray, class SecondArray>
	struct TCompareStaticArraysSequentially<Type, CheckedEquals, Value, Value, FirstArray, SecondArray>
	{
		struct Equals_a : TCompareStaticArraysSequentially<Type, class CheckedEquals::template PushBack<Value>,
			FirstArray::PopFront::Front, SecondArray::PopFront::Front,
			class FirstArray::PopFront, class SecondArray::PopFront>::Equals {}; // WORKS
                
                // *** disambiguate with typename ***
		using Equals_b = typename TCompareStaticArraysSequentially<Type, class CheckedEquals::template PushBack<Value>,
			FirstArray::PopFront::Front, SecondArray::PopFront::Front,
			class FirstArray::PopFront, class SecondArray::PopFront>::Equals; // DOES NOT WORK
	};
// Come to an end of one of the arrays:
	template<class Type, class CheckedEquals, Type FirstValue, Type SecondValue, class Array>
	struct TCompareStaticArraysSequentially<Type, CheckedEquals, FirstValue, SecondValue, TEmptyStaticArray<Type>, Array>
	{
		using Equals = CheckedEquals;
	};
	template<class Type, class CheckedEquals, Type FirstValue, Type SecondValue, class Array>
	struct TCompareStaticArraysSequentially<Type, CheckedEquals, FirstValue, SecondValue, Array, TEmptyStaticArray<Type>>
	{
		using Equals = CheckedEquals;
	};
}

template<class Type, class FirstArray, class SecondArray>
struct TCompareStaticArraysSequentially : Detail::TCompareStaticArraysSequentially<Type, TEmptyStaticArray<Type>,
	FirstArray::Front, SecondArray::Front, FirstArray, SecondArray>::Equals {};

http://coliru.stacked-crooked.com/a/fc19f6d56890fdfa
http://rextester.com/HHYN90382
Oh, that's my bad. I have used "class" specifier instead of "typename" and said it's not working when typename is exactly what it should be. : (
: )
Good, ty.
Topic archived. No new replies allowed.