【问题标题】:What is easiest way to force compiler to throw error?强制编译器抛出错误的最简单方法是什么?
【发布时间】:2017-09-26 17:38:58
【问题描述】:

致将其标记为重复的人:不是;另一个问题解决了enums,它们是编译时常量。这不是一个恒定的积分表达式,因此解决方案将非常不同。在建议已经在另一个问题中回答之前,请更仔细地查看我的代码,因为它没有以任何方式。我正在检查对象上成员变量的值、运行时创建的信息,我很好奇在这种情况下我能用它做什么。


如果我的 API 的用户做了她不应该做的事情,我需要使用 something 使编译器失败。

我不知道这是否可能,是吗?我上面提到的选项主要是运行时的,对吧?

例如,假设你有一个函数:

   void doSomethingIncredible(AwesomeClass amazingObject)
    {
     //perform life-changing work here except:
     if (amazingObject.isntAmazing) //a bool property of object
        //uh oh, life sucks, I refuse to compile this

现在调用这个函数将在各个方面改变你的生活方式,除了 amazingObject 开启了特定属性的情况,例如,在这种情况下,我希望编译器甚至不允许它通过,即无法运行程序。

函数体中的某处是一个强制编译失败的 c++ 机制,它会提醒用户你不能将这个函数用于这样一个低级的、不起眼的对象。

这可能吗?

为了澄清,这是我想根据变量的内容进行编译时的事情,如我上面的示例所示。使用static_assert 的建议不适用于此处。

【问题讨论】:

  • 你见过这个吗? stackoverflow.com/q/6765770/2065121
  • @RogerRowland 值得注意的是,该问题的答案都没有说明如何正确使用 static_assert ,因此我认为该问题是对我的问题的不完整解决方案。您可以看到我对 H2C03 答案的评论
  • 布尔标志isntAmazing 是编译时间常数吗?仅当您在编译时知道某些内容时,才能为信息制作编译器错误。对于运行时值,您需要运行时断言。详细描述AwesomeClass的类型,以便有人可以帮助您。
  • @Fellowshee - 是的,我知道,这就是为什么我不建议它是重复的,只是表明它可能是有用的阅读。

标签: c++


【解决方案1】:

您可以在编译时 static_assert() 一个条件 (C++11)

static_assert(false, "Hey user! You suck!");

或使用

#if (some_erroneous_condition_to_be_avoided)
#error "Hey user! You suck!"
#endif

如果您有 GNU 兼容的编译器(g++clang++ 等)

【讨论】:

  • 我不清楚如何正确使用static_assert。第一个参数需要一个整数常量表达式,但当我只想测试特定变量是真还是假时,我不确定如何创建这样的表达式。这不被认为是断言的正确表达式。
  • @Fellowshee 如果你想检查一个变量是真还是假,那么你不能使用static_assert。您必须在运行时进行验证。
  • MSVC 不支持#error 吗?这是一个标准的 pp 指令(如果您尝试找到它,请查找“#error”)。
  • #error 条件不适用于这个问题,因为这是预处理阶段的事情,甚至在实际编译之前就出现了
【解决方案2】:

我能看到检查编译时间的唯一方法是继承 AwesomeClass 并将新类的创建限制为只能创建 amazingObject.isntAmazing 永远不会为真的对象。然后将签名改为;

void doSomethingIncredible(AwesomeAndAmazingClass amazingObject)

这将阻止对非常棒但并不令人惊叹的对象调用方法。

作为一个可能更具说明性的示例(未编译,因此请考虑伪代码);

class Thing {
  protected: 
    Color _color;
    Shape _shape;
  public:
    Thing(Color color, Shape shape) {
      _color=color; _shape=shape;
    }
}

class GreenThing : Thing {
  public:
    GreenThing(Shape shape) : Thing(Color.Green, shape) {}
}

void doSomethingIncredible(GreenThing specialThing)
{
  // specialThing here is still a Thing, but also compile time
  // checked to also always be a GreenThing
}

【讨论】:

  • 很好的解决方案证明了,即使其他人都说它不能在编译时完成,c++ 特性的新颖使用证明了很多事情都是可能的
【解决方案3】:

这是不可能的。变量的值是在运行时决定的,但是你想根据运行时的值抛出编译时错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-30
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多