如果在C++中,如何通过constexpr跳过不可编译的代码



想象一下下一个没有编译的代码:

在线试用!

#include <type_traits>
#include <iostream>
int main() {
struct A { int i = 123; };
struct B { int j = 456; };
B x;
if constexpr(std::is_same_v<decltype(x), A>)
std::cout << "A: " << x.i;
else if constexpr(std::is_same_v<decltype(x), B>)
std::cout << "B: " << x.j;
}

通过这段代码,我希望有几个不同类型的代码分支。一般来说,我想要不同的分支,不仅针对特定类型,而且针对任何constexpr条件。

上面的代码是不可编译的,因为看起来编译器总是试图编译all-if-constexpr分支,即使它们在编译时有false条件。

当然,我可以通过使用模板结构来解决上面的任务,就像下面的可编译代码一样:

在线试用!

#include <type_traits>
#include <iostream>
template <size_t Id>
struct Code;
template <>
struct Code<0> {
template <typename AT>
void operator()(AT & x){
std::cout << "A: " << x.i;
}
};
template <>
struct Code<1> {
template <typename BT>
void operator()(BT & x){
std::cout << "B: " << x.j;
}
};
int main() {
struct A { int i = 123; };
struct B { int j = 456; };
B x;
Code<std::is_same_v<decltype(x), A> ? 0 : std::is_same_v<decltype(x), B> ? 1 : -1>()(x);
}

但最后一种解决方案有几个缺点——1(它更冗长,需要更多的代码行。2( 它需要全局定义Code结构,因为模板结构只能全局定义。3( 它需要将代码工作所需的所有参数传递/转发给operator((调用。

constexpr变体看起来更优雅,使用起来更直观。有没有办法用if constexpr来解决这样的任务?强制编译器不编译编译时的假分支。

如评论中所述;您必须使丢弃的语句依赖于模板参数"-如果不引入模板,您所要做的事情是不可能的。

例如,这将";工作;但这远不是一个好的解决方案。我添加它作为答案,因为我标记为重复的问题的相似性存在争议。

#include <type_traits>
#include <iostream>
int main() {
struct A { int i = 123; };
struct B { int j = 456; };
B x;

[](auto const & x) {
if constexpr(std::is_same_v<std::remove_cvref_t<decltype(x)>, A>) {
std::cout << "A: " << x.i;
} else if constexpr(std::is_same_v<std::remove_cvref_t<decltype(x)>, B>) {
std::cout << "B: " << x.j;
}
}(x);
}

最新更新