2016-07-12 3 views
3

Можно специализироваться этот шаблон заявление:C++ VARIADIC специализация шаблона (и static_assert)

template <class TYPE, class... ARGS> TYPE Foo(ARGS... args) { 
    static_assert(false); 
} 

Я попробовал несколько вещей, таких как:

template <> int Foo<int>(float args) { 
    return 42; 
} 

... но я всегда хит статические утверждают, когда я пытаюсь использовать его как таковое:

auto value = Foo<int>(1.5f); 

Что такое правильный синтаксис?

+0

Может быть, это просто, что ваш компилятор не поддерживает его так же, как в этом ответе: http://stackoverflow.com/questions/ 7767202/template-specialization-with-variadic-templates? Rq = 1? – Louen

+0

Какой компилятор вы используете? Clang и MSVC компилируют ваш код, а 'value' содержит 42. –

ответ

3

Как состояние, false не является шаблоном зависимого, поэтому static_assert должны стрелять.

Вы можете использовать = delete в вашем случае:

template <class TYPE, class... ARGS> TYPE Foo(ARGS... args) = delete; 

template <> int Foo(float) {return 42;} 

Demo

+0

Недостаточно 'template TYPE Foo (ARGS ... args);' в этом случае? – skypjack

+1

@skypjack: Это была бы ошибка ссылки, тогда как мы могли бы скомпилировать ошибку с '= delete'. – Jarod42

+0

Получил, спасибо. – skypjack

6

Вам не разрешено писать шаблон, который действителен только при условии, что он не создан. Это идет вразрез со следующим правилом в стандарте:

Если действительная специализация не может быть сгенерированы для шаблона, и этот шаблон не создается экземпляр, шаблон плохо сформирован, никаких диагностических не требуется.

С другой стороны, было бы хорошо, если у вас что-то в организме, такие как

static_assert(sizeof(TYPE) != sizeof(int)); 

В таком случае шаблон является действительным, и ваш код будет компилироваться, так как явной специализации фактически будет использоваться вместо первичного шаблона. См. http://coliru.stacked-crooked.com/a/238b979fd10c62c0

-2

Ваше статическое утверждение не зависит от шаблона, поэтому оно всегда срабатывает. Используйте что-то вроде

template <class TYPE, class... ARGS> TYPE Foo(ARGS... args) { 
    static_assert(sizeof(TYPE) != sizeof(TYPE)); 
} 
+0

Это одинаково плохо, даже если компилятор в настоящее время не диагностирует его. –

+0

@TC: он правильно ее диагностирует - правильный диагноз для неудавшегося 'static_assert' является ошибкой ... Поскольку стандартные состояния, этап компиляции, который' static_assert' терпит неудачу, находится в определении шаблона для не зависимых выражений, и создание экземпляров для зависимых выражений. Поэтому, если вы хотите, чтобы 'static_assert' запускался только после создания экземпляра, сделайте его зависимым, даже если само условие не выполняется аргументами шаблона. – Dani

+0

Поскольку действительная специализация этого шаблона не может быть сгенерирована, компилятору разрешено диагностировать это во время определения. Цитата в ответе Брайана. –

Смежные вопросы