[英]deferred selection of types during compile-time
当类型取决于函数中稍后可用的编译时信息时,我是否有一种标准方法可以在 c++20 的编译时选择类型,即由于中间编译时依赖关系,类型被“延迟”。
例如像这样的东西,它依赖于auto
关键字但不编译:
template<bool value, typename ...>
struct bool_type : std::integral_constant<bool , value> {};
template<typename T>
void function(T* v) {
auto r;
bool different_type = false;
if constexpr (...)
r = (T)subfunc_a(v);
else if constexpr (...)
r = (T)subfunc_b(v);
else if constexpr (...)
r = (T)subfunc_c(v);
else if constexpr (...);
r = (T)subfunc_d(v);
else if constexpr (...)
r = (T)subfunc_e(v);
// This condition depends on previous conditions. Extracting the condition
// to the top of this function for use with `std::conditional` would be
// burdensome. Decoupling the conditional in this way also risks errors. I
// want to depend on the type system to enforce code correctness.
else if constexpr (...) {
r = (long)subfunc_f(v);
different_type = true;
}
else if constexpr (...) {
r = (unsigned long)subfunc_g(v);
different_type = true;
}
else {
static_assert(bool_type<false, T>::value, "Unsupported type");
}
do_common_work();
if (different_type)
do_more_work();
*v = r;
}
或者这个例子依赖于static if
提议,它阻止if constexpr
条件创建新范围。 该提案未通过,因此代码无法编译。
template<typename T>
void function(T* v) {
bool different_type = false;
if constexpr (...)
T r = subfunc_a(v);
else if constexpr (...)
T r = subfunc_b(v);
else if constexpr (...)
T r = subfunc_c(v);
else if constexpr (...);
T r = subfunc_d(v);
else if constexpr (...)
T r = subfunc_e(v);
else if constexpr (...) {
different_type = true;
long r = subfunc_f(v);
}
else if constexpr (...) {
different_type = true;
unsigned long r = subfunc_g(v);
}
else {
static_assert(bool_type<false, T>::value, "Unsupported type");
}
do_common_work();
if (different_type)
do_more_work();
*v = r;
}
auto
变量只能从 C++ 中的初始化表达式推断其类型。 如果您不想显式指定其类型,则可以将初始化提取到一个单独的函数中,该函数return
s 必要的值(类型为auto
)并使用此函数的调用进行初始化。
特别是,提取的函数可以是 lambda 表达式,因此您会得到一个立即调用的函数表达式或 IIFE:
#include <iostream>
#include <type_traits>
template <bool value, typename...>
struct bool_type : std::integral_constant<bool, value> {};
template <typename T> void function(T *v) {
bool different_type = false;
auto r = [&] { // create a function
if constexpr (std::is_same_v<T, int>) {
return 10;
} else if constexpr (std::is_same_v<T, double>) {
return 10.0;
} else if constexpr (std::is_same_v<T, long>) {
different_type = true;
return 10LL;
} else {
static_assert(bool_type<false, T>::value, "Unsupported type");
}
}(); // immediately invoke the created function
std::cout << typeid(r).name() << " " << different_type << "\n";
*v = r;
}
int main() {
int a;
double b;
long c;
[[maybe_unused]] float d;
function(&a); // int 0
function(&b); // double 0
function(&c); // long long 1
// function(&d); // compilation error
}
在上面的代码中,lambda 表达式的返回类型为auto
,即它是从if constexpr
选择的return
值中自动推导出来的。 只选择了一个返回,所以返回类型是明确的,所以r
的类型也被正确推断。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.