Reputation: 16741
How to introduce static_assert
into template variable definition?
My attemption is to use lambda function:
#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;
}
But for non-moveable objects it is impossible to construct the value object in such a manner.
Using comma operator I can't perform value-initialization in form F f = ([] () { static_assert(std::is_default_constructible< F >{}); }(), {});
.
I can't use additional template parameter in form , typename = decltype([] () { static_assert(std::is_default_constructible< F >()); })
, due to it is an error lambda expression in an unevaluated operand
.
Disabling instantiation by SFINAE is not the solution. I do need static_assert
to say user about error explicitly.
It would be nice if static_assert
return void
or bool
.
Upvotes: 2
Views: 710
Reputation: 171413
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{};
}
Or so the check appears directly in the variable template:
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{};
}
Upvotes: 5