2015-09-25 9 views
1

Как ввести static_assert в определение переменной шаблона?Как ввести static_assert в определение переменной шаблона

Мой attemption является использование функции лямбда:

#include <type_traits> 
#include <utility> 

#include <cstdlib> 

namespace 
{ 
#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Wglobal-constructors" 

template< typename F > 
F f = ([]() { static_assert(std::is_default_constructible<F>{}); }(), F{}); 

#pragma clang diagnostic pop 
} 

struct L 
{ 
    L() = default; 
    L(L const &) = delete; 
    L(L &&) = delete; 
}; 

int 
main() 
{ 
    static_cast<void>(f<L>); 
    return EXIT_SUCCESS; 
} 

Но для не перемещаемых объектов, невозможно построить объект значения таким образом.

Использование оператора запятой Я не могу выполнить инициализацию значения в форме F f = ([]() { static_assert(std::is_default_constructible<F>{}); }(), {});.

Я не могу использовать дополнительный параметр шаблона в форме , typename = decltype([]() { static_assert(std::is_default_constructible<F>()); }), из-за ошибки lambda expression in an unevaluated operand.

Отказ от создания экземпляра SFINAE не является решением проблемы. Мне нужно static_assert, чтобы явно сказать пользователю об ошибке.

Было бы неплохо, если static_assert возвращение void или bool.

+1

'шаблон <имяТип F> класс F_class {static_assert (...); используя тип = F; }; template typename F :: type f; ' – zch

+0

@zch' struct' instad of 'class' is right – Orient

+0

С SFINAE сообщение об ошибке не очень понятно :([Demo] (http: //coliru.stacked- crooked.com/a/f3b79dcc2d79186a) – Jarod42

ответ

3
template<typename T> 
struct require_default_constructible { 
    static_assert(std::is_default_constructible<T>{}, "is default constructible"); 
    using type = T; 
}; 

namespace 
{ 
template< typename F > 
    typename require_default_constructible<F>::type f{}; 
} 

Или такая проверка появляется непосредственно в переменном шаблоне:

template<typename T, bool B> 
struct check { 
    static_assert(B, "???"); 
    using type = T; 
}; 

namespace 
{ 
template< typename F > 
    typename check<F, std::is_default_constructible<F>::value>::type f{}; 
} 
+0

Второй вариант - это точное решение. Оно ясно говорит о том, что непосредственно проверяется на определение переменных шаблона. – Orient

+1

I по-прежнему считают, что это пустая трата времени, утверждая, что то, что вы по умолчанию строите по умолчанию, конструктивно. –

+0

* По умолчанию конструктив * является всего лишь примером. Я рассматриваю общую проблему. – Orient