如何在模板变量定义中引入static_assert
How to introduce static_assert into template variable definition
如何在模板变量定义中引入static_assert
?
我的尝试是使用 lambda 函数:
#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
return void
或者bool
就好了。
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{};
}
如何在模板变量定义中引入static_assert
?
我的尝试是使用 lambda 函数:
#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
return void
或者bool
就好了。
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{};
}