What's the point of this error?

1
2
3
4
5
6
7
8
9
10
11
struct Outer
{
	template<typename T>
	struct Inner
	{
	};
	template<>
	struct Inner<double>
	{
	};
};
prog.cpp:9:11: error: explicit specialization in
                      non-namespace scope ‘struct Outer’
  template<>
           ^
http://ideone.com/sxyQBg
What's the point of the error when you can just get around it?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct Outer
{
	template<typename T, typename = void>
	struct Inner
	{
	};
	template<typename T>
	struct Inner
	<
		typename std::enable_if
		<
			std::is_same<T, double>::value,
			T
		>::type,
		T
	>
	{
	};
};
http://ideone.com/IThuo2
What's the point of the error when you can just get around it?


The error makes the compiler compliant with the standard?

http://ideone.com/XxOvH2
@JLBorges: Ah, that makes a little sense. Thanks!

@cire: unfortunately that's not an option because later in the class Outer, the specializations of Inner need to exist to be used.
Last edited on
@cire: unfortunately that's not an option because later in the class Outer, the specializations of Inner need to exist to be sued.

Is that really an issue?

http://ideone.com/X5dZvg
That's not very hard to avoid. Btw, I was curious, as well, about the rationale for not allowing explicit specializations inline.

This was the closest thing I could find, which seems to suggest it was put off and then, perhaps, forgotten?
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#44
> That's not very hard to avoid.

This will not avoid the error, if "in the class Outer, the specializations of Inner need to exist to be used.":
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct Outer
{
    template < typename U > struct Inner {} ;

    Inner<int> a ;
    Inner<double> b ;
};

// *** error: specialization of 'Outer::Inner<double>' after instantiation|
template<> struct Outer::Inner<double> {};

int main()
{
	Outer o;
}


This will:
1
2
3
4
5
6
7
8
9
10
11
12
13
struct Outer
{
    template < typename U, typename = void > struct Inner {} ;
    template < typename VOID > struct Inner<double,VOID> {};

    Inner<int> a ;
    Inner<double> b ;
};

int main()
{
	Outer o;
}
JLBorges wrote:
3
4
template < typename U, typename = void > struct Inner {} ;
template < typename VOID > struct Inner<double,VOID> {};
Is this equivalent to my enable_if version? if so, I'll switch to this more terse version instead.
Last edited on
> Is this equivalent to my enable_if version?

Yes.

Both are technically partial specializations (which are allowed because they are subject to two phase name lookup, with dependant names resolved later during phase two).
Topic archived. No new replies allowed.