声明一个返回void的函数是否有任何理由使用constexpr?

13 浏览
0 Comments

声明一个返回void的函数是否有任何理由使用constexpr?

这是我阅读的内容:使用别名来定义静态成员函数?\n在答案中,我看到有建议使用constexpr。为什么要对void函数使用constexpr?\n请展示一个简单的用例。我对constexpr还不熟悉,所以复杂的例子我可能无法理解要点。

0
0 Comments

声明一个返回void的函数为constexpr的原因是为了在编译时计算地址。在嵌入式编程中,有时需要将外设的地址设置为固定值。为了实现这一点,需要在链接脚本中指定外设所在的固定地址。然后,可以使用一个constexpr函数来设置这个地址对应的变量的值。

在上面的例子中,通过一个名为gpio_t的POD(Plain Old Data)结构体来模拟外设。该结构体只有一个成员变量mode,这个成员变量是volatile类型的,可以在编译时设置其值。在init函数中,将mode设置为了一个常量值。虽然在这个例子中使用函数来设置变量的值没有任何好处,但在实际的应用中,可能需要根据一些计算来设置变量的值和地址,比如设置波特率的分频器。

需要注意的是,不能使用C风格的整数转换为地址的方式来设置constexpr指针,因为reinterpret_cast不符合创建constexpr指针的要求。在C++14中已经禁止这样的操作。

解决这个问题的方法是使用一个固定地址的变量来表示外设的地址,然后通过一个constexpr函数来设置这个变量的值。这样,在编译时就可以计算出外设的地址,并将其作为常量使用。

struct gpio_t {
    volatile std::uint32_t mode;
};
__attribute__ ((section (".GPIO"))) gpio_t Gpio = {0};
static constexpr gpio_t *port {&Gpio};
static constexpr void init () {
    port->mode = 42u;
};
void main {
    init ();
    // ...
};

需要注意的是,上面的例子只是为了说明问题,实际的应用中可能会更复杂。但无论如何,通过将函数声明为constexpr,可以在编译时计算出变量的值和地址,从而提高代码的效率和可靠性。

0
0 Comments

声明一个返回void的函数为constexpr的原因是,根据C++ 14标准,void是一种字面类型。根据标准,任何表达式都是允许的,以便允许调用执行检查的函数和允许类似于assert的构造。同时,void也成为了字面类型,因此constexpr函数可以返回void,这样的函数主要是用于执行检查。

简单的使用案例如下:

constexpr void performCheck(int value) {

if (value < 0) {

throw std::runtime_error("Value cannot be negative.");

}

}

在上述示例中,performCheck函数是一个constexpr函数,返回类型为void。它用于检查传入的value是否为负数,如果是,则抛出一个运行时错误。通过将该函数声明为constexpr,可以在编译时进行静态检查,并确保传入的值不会导致运行时错误。

解决方法是将返回类型声明为void,并将函数声明为constexpr。这样可以确保函数在编译时进行静态检查,并且在执行期间不会引发任何异常。这在需要在编译时进行检查的情况下非常有用,以避免运行时错误。

0
0 Comments

有没有理由声明返回void的函数为constexpr?

Rahul的答案引用了标准段落,允许void constexpr函数,但没有给出用例。我想到的一个用例是拥有constexpr类,并像往常一样将方法中的行为提取出来作为辅助方法。标准明确提到了执行检查的函数,例如断言。我手头上没有具体的例子,但我可以想象出类似于下面这样的东西:

class A
{
public:
    constexpr X doSomething(Y arg1) {
        checkInvariant();
        constraintOnYArgument(arg1);
        // ...
        checkInvariant();        
    }
    constexpr X doSomethingElse(Y arg1) {
        checkInvariant();
        constraintOnYArgument(arg1);
        // ...
        checkInvariant();        
    }
private:
    constexpr void constraintOnYArguments(Y arg) {
    }
    constexpr void checkInvariant() {
        // some checks
        if (!some condition) {
            throw std::logic_error("Oh no!");
        }
    }
};

我认为这个回答更有用。特别是在c++11中,您可以在constexpr函数中使用throw。

0