如何在不使用临时变量的情况下使用 constexpr 调用运算符?
How to call an operator with constexpr without using temporary variables?
下面的示例代码说明了我的问题。
constexpr int fact(int N) {
return N ? N * fact(N - 1) : 1;
}
struct A {
int d;
constexpr A operator+(const A& other) const { return A{ fact(d + other.d) }; }
// overload of many other operators
};
int main() {
int x;
cin >> x; // run time argument
constexpr A a{ 2 }, b{ 3 };
A c{ x };
A u = a + b + c; // both + eval at run time
//constexpr A v = a + b + c; // doesn't compile because c is not constant
}
我想要实现的是第一个 operator+
在编译时求值,第二个 operator+
在 运行 时求值。
当然可以分解成
constexpr A tmp = a + b;
A u = tmp + c;
但在我的例子中,重载运算符的全部意义在于允许以更直观的方式构建更复杂的公式,这样会使重载毫无意义。
如果我将 operator+
声明为 consteval
,那么它又不会编译。而且我不能重载它两次。
有解决办法吗?
不,至少在 gcc 中并经过优化,here 您可以看到它在编译时求值。 (120
)
main:
mov eax, 1
add edi, 120
je .L4
.L3:
imul eax, edi
sub edi, 1
jne .L3
ret
.L4:
ret
*公平地说,即使没有 constexpr
编译器也可能会对其进行优化。
您可以使用 (non-type) 模板参数或 consteval
函数强制计算。
constexpr int fact(int N) {
return N ? N * fact(N - 1) : 1;
}
struct A {
int d;
constexpr A operator+(const A& other) const { return A{ fact(d + other.d) }; }
};
consteval auto value(auto v){return v;}
A foo (int x) {
constexpr A a{ 2 }, b{ 3 };
A c{ x };
A u = value(a+b) + c;
return u;
}
下面的示例代码说明了我的问题。
constexpr int fact(int N) {
return N ? N * fact(N - 1) : 1;
}
struct A {
int d;
constexpr A operator+(const A& other) const { return A{ fact(d + other.d) }; }
// overload of many other operators
};
int main() {
int x;
cin >> x; // run time argument
constexpr A a{ 2 }, b{ 3 };
A c{ x };
A u = a + b + c; // both + eval at run time
//constexpr A v = a + b + c; // doesn't compile because c is not constant
}
我想要实现的是第一个 operator+
在编译时求值,第二个 operator+
在 运行 时求值。
当然可以分解成
constexpr A tmp = a + b;
A u = tmp + c;
但在我的例子中,重载运算符的全部意义在于允许以更直观的方式构建更复杂的公式,这样会使重载毫无意义。
如果我将 operator+
声明为 consteval
,那么它又不会编译。而且我不能重载它两次。
有解决办法吗?
不,至少在 gcc 中并经过优化,here 您可以看到它在编译时求值。 (120
)
main:
mov eax, 1
add edi, 120
je .L4
.L3:
imul eax, edi
sub edi, 1
jne .L3
ret
.L4:
ret
*公平地说,即使没有 constexpr
编译器也可能会对其进行优化。
您可以使用 (non-type) 模板参数或 consteval
函数强制计算。
constexpr int fact(int N) {
return N ? N * fact(N - 1) : 1;
}
struct A {
int d;
constexpr A operator+(const A& other) const { return A{ fact(d + other.d) }; }
};
consteval auto value(auto v){return v;}
A foo (int x) {
constexpr A a{ 2 }, b{ 3 };
A c{ x };
A u = value(a+b) + c;
return u;
}