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

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

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

#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,

2

Решение

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{};
}
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]