Template specialization in non-namespace scope

Jul 2, 2016 at 11:25am
Hi.

Look at this piece of code. (compiles on MSVC++, doesn't compile on gcc and clang)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>

using namespace std;

template<bool CONDITION, typename THEN, typename ELSE>
struct IF
{
    template<bool C>
    struct selector { using selected = THEN; };

    template<>
    struct selector<false> { using selected = ELSE; };

    using result = typename selector<CONDITION>::selected;
};


It says: "error: explicit specialization of 'selector' in class scope"

Reading around on the internet, it turned out I need to export the struct specialization outside the struct(first question: WHY???)

So I tried:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>

using namespace std;

template<bool CONDITION, typename THEN, typename ELSE>
struct IF
{
     template<bool C>
     struct selector { using selected = THEN; };

//      template<>
//	struct selector<false> { using selected = ELSE; };

     using result = typename selector<CONDITION>::selected;
};

// SPECIALIZATION OUTSIDE THE CLASS!
template<>
struct IF::selector<false> { using selected = ELSE; };


The problem now is that it says I need to specify template arguments for IF, on line
 
struct IF<...here...>::selector<false> { using selected = ELSE; };


What do I write there? How do I go on at this point?
Last edited on Jul 2, 2016 at 12:46pm
Jul 2, 2016 at 2:02pm
The C++ standard does not allow explicit specialization of a member of a class at class scope.

A canonical work-around to allow what in effect would behave like an explicit specialization inside the class is to use an extra unused template parameter with a default value:
1
2
3
4
5
6
7
8
9
10
11
template<bool CONDITION, typename THEN, typename ELSE>
struct IF
{
    template< bool C, typename fake = void >
    struct selector { using selected = THEN; };

    template< typename fake >
    struct selector<false,fake> { using selected = ELSE; };

    using result = typename selector<CONDITION>::selected;
};


Note: The standard library has std::conditional<> http://en.cppreference.com/w/cpp/types/conditional
Jul 2, 2016 at 2:07pm
Note: The standard library has std::conditional<>

I know about std::conditional<>, otherwise I couldn't have ever imagined to do something similar ^^

The C++ standard does not allow explicit specialization of a member of a class at class scope.

Seems a pretty strange decision. Who knows... they must have their reasons...

What is stranger is that MSVC++ compiles fine... should I be worried?
Last edited on Jul 2, 2016 at 2:08pm
Jul 2, 2016 at 2:22pm
> Seems a pretty strange decision. Who knows... they must have their reasons...

See: http://www.cplusplus.com/forum/general/58906/#msg318049


> What is stranger is that MSVC++ compiles fine... should I be worried?

No. For this, the Microsoft compilers are known to be non-conforming.
(Not sure if they fixed it in the recent Update 3.)
Topic archived. No new replies allowed.