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

时间:2016-02-12 06:29:24

标签: c++ c++11

以下是我读到的内容:using alias for static member functions?

在答案中,我看到了使用constexpr的建议。将constexpr用于void函数的原因是什么。

请演示一个简单的用例。我是constexpr的新手,所以在复杂的例子中我不理解要点。

4 个答案:

答案 0 :(得分:5)

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!");
        }
    }
};

答案 1 :(得分:2)

根据C ++ 14标准,void是文字类型

  

类型是文字类型,如果它是:

     

- 无效;或

     

- 标量类型;或

     

- 参考类型;或

     

- 一个文字类型的数组;或

     

- 具有以下所有属性的类类型(第9条): -   它有一个简单的析构函数,

     

- 它是聚合类型(8.5.1)或至少有一个constexpr   不是复制或移动的构造函数或构造函数模板   构造函数和

     

- 所有非静态数据成员和基类都是   非易失性文字类型。

来自here

  

允许使用任意表达式语句   调用执行检查的函数并允许类似断言   结构体。 void也成为文字类型,因此constexpr   仅存在执行此类检查的函数可能会返回void。

答案 2 :(得分:1)

合理的用例是对 volatile 变量的操作。以下是使用GNU工具(g ++,ld)进行嵌入式编程的非常简化案例:

要将外围设备的地址设置为constexpr,您需要将其放置在固定位置。这必须在链接描述文件中完成:

⋮
/* Define output sections */
SECTIONS
{
GPIO    0x48000000 (NOLOAD) : { *(.GPIO) }
⋮

现在,.GPIO部分位于固定地址0x48000400。外围设备可以通过包含易失性成员的POD建模。在以下示例中,POD名为gpio_t,并且只有一个成员:mode。可以在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 ();
    ⋮
};

注意:将整数强制转换为地址的C样式惯用法不起作用,因为它reinterpret_cast<>不符合创建constexpr指针的条件(请参见Since C++14 illegal)。以下失败

constexpr gpio_t *port {(gpio_t *) 0x48000400};

答案 3 :(得分:0)

只要参数号是一个整数常量,这个constexpr版本将在编译时计算结果(仅限C ++ 11编译器)。当数字是运行时整数时,同样的函数完全能够在运行时计算结果。因此,您不需要同一程序的两个不同版本:一个用于编译时,另一个用于运行时。一个实现就是全部。