【问题标题】:C++11 static_assert: Parameterized error messagesC++11 static_assert:参数化错误消息
【发布时间】:2012-06-15 12:18:32
【问题描述】:

在my previous question 中,我想使用 static_assert 将模板参数限制为特定的子类型。问题得到解答,存档代码如下:

template <typename T> 
struct X { 
    static_assert(std::is_base_of<Y,T>::value,"T must be derived from Y!");
};

现在,我想让错误信息更简洁。即,我想说明哪种类型违反了此约束。例如,如果类 A 不是从 Y 派生的,并且有人实例化了 X&lt;A&gt;,则错误消息应打印“类型参数必须从 Y 派生,但 A 不是” .

这是否可以通过标准库以某种方式实现?

我看到了两个挑战:

  • 在编译时组装字符串而不使用 boost::mpl
  • 检索实例化 T 的类型的名称。名称应该有意义,理想情况下与违规定义中使用的名称相同。我试过 typeid(T).name() 但它只返回不可接受的损坏名称。我记得有一种宏可以返回某物的名称,但我想不起来了。

【问题讨论】:

标签: c++ templates c++11 assertions static-assert


【解决方案1】:

你不能这样做。 static_assert 想要一个字符串文字。您无法将T 和Y 的语义标识组装到字符串文字中。

您可以希望编译器提供一个易于阅读的模板实例化堆栈的回溯,并为您提供封闭类模板实例化的T 和Y 模板参数的值。

其他人也想过这个,例如http://comments.gmane.org/gmane.comp.compilers.clang.devel/5073。

【讨论】:

  • 一如既往地用于诊断,这是一个 QOI。
  • 真可惜。为什么文字,编译时常量字符串会更好:(。
  • @gexicide 无论如何,形成编译时常量字符串通常是不切实际的。 (当然,除了文字。)打印一系列任意编译时常量值和/或类型 ID 的值会很好。
  • 链接已失效。
【解决方案2】:

您仍然可以使用 BOOST_MPL_ASSERT_MSG。它接受泛型类型作为参数,并尝试在错误消息中包含具体类型名称。

更多信息和示例在这里: http://www.boost.org/doc/libs/1_49_0/libs/mpl/doc/refmanual/assert-msg.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-05-29
    • 2012-01-03
    • 1970-01-01
    相关资源
    最近更新 更多