【问题标题】:How to introduce static_assert into template variable definition如何在模板变量定义中引入 static_assert
【发布时间】:2015-09-25 12:15:51
【问题描述】:

如何在模板变量定义中引入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&lt; F &gt;{}); }(), {}); 形式执行值初始化。

我不能在表单, typename = decltype([] () { static_assert(std::is_default_constructible&lt; F &gt;()); }) 中使用额外的模板参数,因为它是一个错误lambda expression in an unevaluated operand

通过 SFINAE 禁用实例化不是解决方案。我确实需要static_assert 明确地向用户说明错误。

如果static_assert 返回voidbool,那就太好了。

【问题讨论】:

  • template&lt; typename F &gt;class F_class{ static_assert(...); using type=F; }; template&lt; typename F &gt; typename F::type f;
  • @zch struct instad of class 是对的
  • 使用SFINAE,错误信息不是很清楚:(Demo
  • @zch 严格来说我想将static_assert直接引入到变量模板定义中。
  • 为什么?如果它不是默认可构造的,那么变量模板定义无论如何都会告诉你。代码的混淆真的值得稍微更好的错误消息吗?

标签: c++ c++14 typetraits static-assert variable-templates


【解决方案1】:
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{};
}

【讨论】:

  • 第二种变体是精确解。它清楚地说明了直接检查变量模板定义的内容。
  • 我仍然认为断言你默认构造的东西是默认构造是浪费时间。
  • DefaultConstructible 只是一个例子。我考虑一般问题。
猜你喜欢
  • 2019-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-08
  • 2011-10-23
  • 1970-01-01
  • 1970-01-01
  • 2017-10-15
相关资源
最近更新 更多