从constexpr返回对象?

时间:2018-02-05 14:18:24

标签: c++ static constexpr

如何从constexpr函数返回一个对象?根据{{​​3}},您无法使用new,但我该怎么办呢?有可能吗?我想使用函数的参数初始化一个对象并将其返回,但似乎无法弄清楚如何。

示例:

struct Test {
    int a;
    constexpr Test (int b): a(b) {};
    Test(const Test& a);
};

Test::Test(const Test& t) {
    this->a = t.a;
}

constexpr Test set_test(int a) {
    return Test(a);
}

int main() {
    return 0;
}

2 个答案:

答案 0 :(得分:2)

我对公开的示例代码做了一些小的补充,以便使用set_test()并阻止优化死代码:

#include <iostream>

struct Test {
    int a;
    constexpr Test (int b): a(b) {};
    Test(const Test& a);
};

Test::Test(const Test& t) {
    this->a = t.a;
}

constexpr Test set_test(int a) {
    return Test(a);
}

int main() {
  std::cout << "set_test(1).a: " << set_test(1).a << std::endl;
    return 0;
}

这在ideone中工作正常。

它声明使用C++ (gcc 6.3)

因此,我正在寻找另一个在线编译,我可以选择clang并找到Wandbox

使用clang HEAD 7.0.0无法编译。如果我做对了set_test()尝试使用不是constexpr的复制构造函数。

因此,我delete是复制构造函数。现在,它在return Test(a);中失败,因为它试图访问已删除的复制构造函数。奇怪...

所以,我最终提供了一个move-constructor

constexpr Test(Test &&test): a(test.a) { }

替换已删除的拷贝构造函数。现在,它编译并运作:

#include <iostream>

struct Test {
    int a;
    constexpr Test (int b): a(b) {}
    Test(const Test& a) = delete;
    constexpr Test(Test &&test): a(test.a) { }
};

#if 0
Test::Test(const Test& t) {
    this->a = t.a;
}
#endif // 0

constexpr Test set_test(int a) {
    return Test(a);
}

int main() {
  std::cout << "set_test(1).a: " << set_test(1).a << std::endl;
    return 0;
}

输出:

Start

set_test(1).a: 1

0

Finish

Wandbox上的生活演示。

出于好奇,我再次修改了示例以尝试使复制构造函数constexpr也能修复。确实如此。

Wandbox上的生活演示。

答案 1 :(得分:1)

您可以使用某种类型constexpr的参数化T函数,返回类型为T的值,T为用户定义的类。简单的例子:

#include <iostream>

struct A {
private:
    int x;
public:
    constexpr A(int x) : x(x) {};
    void print() {
        std::cout << x;
    }
};

constexpr A foo(int p) {
    A temp{ p };
    return temp;
}

int main() {
    A o = foo(123);
    o.print();
}

constexpr函数的重点是它的返回类型满足constant expression要求。