考虑以下程序:
#include <iostream>
#include <type_traits>
constexpr int f() {
if (std::is_constant_evaluated())
return -1;
else return 1;
}
int main() {
int const i = f();
std::cout << i;
}
Run Code Online (Sandbox Code Playgroud)
它打印-1在运行时(wandbox)。
但是,如果我throw在编译时求值时使用该函数:
#include <iostream>
#include <type_traits>
constexpr int f() {
if (std::is_constant_evaluated())
throw -1; // <----------------------- Changed line
else return 1;
}
int main() {
int const i = f();
std::cout << i;
}
Run Code Online (Sandbox Code Playgroud)
它可以编译并输出1(wandbox)。为什么我没有出现编译失败?
在 C++20 中,我们可以这样写:
double x;
double x_value = std::atomic_ref(x).load();
Run Code Online (Sandbox Code Playgroud)
有没有同样效果的功能?
我试过,std::atomic_load但似乎没有非原子对象的重载。
我有一个有限体积库,受到openfoam 的强烈影响,它可以像在纸上一样用 C++ 编写连续介质力学问题的解决方案。例如,要求解不可压缩层流的 Navier-Stokes 方程,我简单地写:
solve(div(U * U) - nu * lap(U) == -grad(p));
Run Code Online (Sandbox Code Playgroud)
当然,这个表达式涉及表达式模板,因此系统系数是单次计算的,并且系统以无矩阵的方式求解。
这些表达式模板基于 CRTP,因此所有必需的运算符都在基类中定义。特别是,相等运算符的定义如下:
template <typename T>
class BaseExpr {};
template <std::size_t dim, std::size_t rank, typename... TRest,
template <std::size_t, std::size_t, typename...> typename T>
class BaseExpr<T<dim, rank, TRest...>>
{
// ...
public:
template <typename... URest, template <std::size_t, std::size_t, typename...> typename U>
SystemExpr<dim, rank, T<dim, rank, TRest...>, U<dim, rank, URest...>>
operator ==(BaseExpr<U<dim, rank, URest...>> const &rhs) const
{ return {*this, rhs}; }
SystemExpr<dim, rank, T<dim, rank, …Run Code Online (Sandbox Code Playgroud) 我刚刚从 Saar Raz 的演示视频中了解到以下限制:
template <typename T>
concept C = sizeof(T) > 1;
template <typename T>
concept D = sizeof(T) > 1 && sizeof(T) >= 4;
Run Code Online (Sandbox Code Playgroud)
对重载不明确,因为分别sizeof(T) > 1出现在C和的原子约束D不等价。
他们不是因为标准说[templ.constr]:
两个原子约束是相同的,如果它们是由相同的形成表达[...]
关键是表达式是斜体,指的是语法术语,定义为[expr.comma]:
表达:
赋值表达式
表达式,赋值表达式
我不明白为什么原子约束需要涉及赋值。为什么会这样?
我必须承认,上面的代码最好通过概念细化来编写,但我直觉地认为这种编写方式也是正确的。