What's the point of this error?

Nov 17, 2013 at 5:54am
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
Nov 17, 2013 at 6:06am
Nov 17, 2013 at 6:09am
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
Nov 17, 2013 at 6:09am
@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 Nov 17, 2013 at 8:03pm
Nov 17, 2013 at 6:23am
@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
Nov 17, 2013 at 6:28am
Nov 17, 2013 at 9:55am
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
Nov 17, 2013 at 7:28pm
> 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;
}
Nov 17, 2013 at 8:15pm
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 Nov 17, 2013 at 8:16pm
Nov 17, 2013 at 8:24pm
> 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.