Сбой специализации std :: enable_if - PullRequest
1 голос
/ 27 сентября 2011

Я возился с enable_if и, похоже, наткнулся на какое-то непоследовательное поведение. Это в VS2010. Я сократил его до следующего образца.

#include <type_traits>

using namespace std;

// enable_if in initial template definition
template <class T, class Enable = enable_if<true>> struct foo {};

foo<int> a; //OK

// explicit specialisation
template <class T, class Enable = void> struct bar;
template <class T> struct bar<T, void> {};

bar<int> b; //OK

// enable_if based specialisation
template <class T, class Enable = void> struct baz;
template <class T> struct baz<T, std::enable_if<true>> {};

baz<int> c; //error C2079: 'c' uses undefined struct 'baz<T>'

Это ошибка в коде или компиляторе?

Ответы [ 2 ]

6 голосов
/ 27 сентября 2011

std::enable_if<true> должно быть typename std::enable_if<true>::type.

std::enable_if<true> всегда называет тип (как и std::enable_if<false>).Для того, чтобы подстановка потерпела неудачу, когда условие ложно, вам нужно использовать type вложенный typedef, который определяется, только если условие истинно.

3 голосов
/ 27 сентября 2011

Ваша проблема имеет очень мало общего с enable_if

// you declare a structure named baz which takes 2 template parameters, with void
// as the default value of the second one.
template <class T, class Enable = void> struct baz;
// Partial specialization for a baz with T and an std::enable_if<true>
template <class T> struct baz<T, std::enable_if<true>> {};

// Declare a baz<int, void> (remember the default parameter?):
baz<int> c; //error C2079: 'c' uses undefined struct 'baz<T>'

baz<int, void> имеет неполный тип в этой точке.Та же проблема возникнет без enable_if:

template <class T, class U = void>
struct S;

template <class T>
struct S<T, int>
{ };

S<double> s;

И, как сказал Джеймс, вы неправильно используете enable_if. Документация Boost для enable_if прекрасно объясняет это.

...