强制编译器报错的最简单方法是什么?

7
对于将此标记为重复的人:这并不是重复的问题;其他问题涉及编译时常量enum。这不是一个常数整数表达式,因此解决方案会非常不同。在建议已经在其他问题中得到解答之前,请仔细查看我的代码。我正在检查对象上的成员变量的值,这些信息是在运行时创建的,并且我很好奇在这种情况下我能做些什么。

我现在需要使用某些东西,如果我的 API 的用户做了一些不应该做的事情,让编译器失败。

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

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

   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在此处不适用。

你看过这个吗?https://dev59.com/RGw15IYBdhLWcg3wMY-L - Roger Rowland
值得注意的是,那个问题的所有答案都没有展示如何正确使用 static_assert,所以我认为那个问题并没有完全解决我的问题。你可以看到我对 H2C03 回答的评论。 - johnbakers
1
bool标志isntAmazing是编译时常量吗?如果您在编译时知道某些信息,可以使编译器仅出现错误信息。对于运行时值,您需要运行时断言。更详细地描述AwesomeClass的类型,以便有人可以帮助您。 - iammilind
@Fellowshee - 是的,我知道,这就是为什么我没有建议它是一个重复的问题,只是表明它可能是一个有用的阅读材料。 - Roger Rowland
3个回答

20

你可以在编译时使用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。第一个参数需要一个整数常量表达式,但是当我仅想测试特定变量的真假时,我不确定如何创建这样的表达式。这不被认为是断言的正确表达式。 - johnbakers
3
如果你想检查一个变量是真还是假,那么你不能使用 static_assert。你需要在运行时验证。 - user529758
MSVC不支持#error吗?这是一个标准的预处理指令(如果你想找到它,请查找“# error”)。 - chris
2
“#error” 条件不适用于这个问题,因为它是在预处理阶段出现的,并且比实际编译还要早。 - iammilind

3
我认为实现编译时检查的唯一方法是通过子类化AwesomeClass并限制新类的创建,使其只能创建amazingObject.isntAmazing永远不为true的对象。然后更改签名为:
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++特性,可以用一些思考实现很多事情。 - johnbakers

1

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接