gpt4 book ai didi

c++ - 模仿 "if constexpr"行为,不可能?

转载 作者:太空狗 更新时间:2023-10-29 21:15:01 24 4
gpt4 key购买 nike

我的编译器不支持 if constexpr,但我被它的好处所吸引。
我必须拥有它 - 即使它可能是假的。

这段代码是我试图模仿 if constexpr 行为。
目标是使行 (###) 仅出现在 1 个函数中:-

#include <iostream>
using namespace std;

template<bool Flag,typename F> constexpr typename std::enable_if<!Flag, void>::type iter_(F f,int i1){
f(i1); //No! The compiler still tried to compile even Flag=true
}
template<bool Flag,typename F> constexpr typename std::enable_if<Flag, void>::type iter_(F f,int i1){ }
template<bool Flag,typename F> constexpr typename std::enable_if<Flag, void>::type iter_(F f,int i1,int i2){
f(i1,i2); //No! The compiler still tried to compile even Flag=false
}
template<bool Flag,typename F> constexpr typename std::enable_if<!Flag, void>::type iter_(F f,int i1,int i2){}

template<bool Flag,typename F> constexpr void fff( F f ){
for(int n=0;n<5;n++){//fake loop, the real situation is very complex
//### some horror code appeared here, but omitted
if(Flag){//attempt to mimic "if constexpr"
iter_<true>(f,1,2);
}else{
iter_<false>(f,3);
}
}
}

这是它的用法:-

template<typename F> constexpr void fff1(  F f  ){fff<false>(f);} //usage
template<typename F> constexpr void fff2( F f ){fff<true>(f);} //usage

int main() {
// your code goes here
auto f1=[&](int a){
cout<<a<<" ";
};
auto f2=[&](int a,int b){
cout<<a<<" "<<b<<endl;
};
fff1(f1);
fff2(f2);
return 0;
}

编译错误:

prog.cpp: In instantiation of 'constexpr typename std::enable_if<Flag, void>::type iter_(F, int, int) [with bool Flag = true; F = main()::<lambda(int)>; typename std::enable_if<Flag, void>::type = void]':
prog.cpp:16:18: required from 'constexpr void fff(F) [with bool Flag = false; F = main()::<lambda(int)>]'
prog.cpp:22:61: required from 'constexpr void fff1(F) [with F = main()::<lambda(int)>]'
prog.cpp:33:9: required from here
prog.cpp:9:3: error: no match for call to '(main()::<lambda(int)>) (int&, int&)'
f(i1,i2);
^
prog.cpp:9:3: note: candidate: void (*)(int) <conversion>
prog.cpp:9:3: note: candidate expects 2 arguments, 3 provided

从错误中,我很清楚即使一个函数有 std::enable_if[ effective FALSE],
编译器仍然编译函数内部的代码。 - 那很不好。

我必须编辑哪些部分?
...或者有其他选择吗?
... 或者根本不可能模仿 if constexpr(这就是最终引入它的原因)?

最佳答案

阅读:http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0128r1.html

Can't we do this with existing language features?

John Spicer suggested in c++std-ext-17099 that polymorphic lambdas combined with a decision-making template would provide an adequate facility without a need to add new language features. The invocation of that decision-making template looks roughly like this:

template <int arg, typename ... Args> int do_something(Args... args) {
return static_if<sizeof...(args)>::get(
[](auto x, auto y) { return x+y; },
[](auto x) { return *x; })(args...);
}

Now, in comparison, with the proposed language facility, we do

template <int arg, typename ... Args> int do_something(Args... args) {
constexpr if (sizeof...(args)) {
return (args + ...);
} constexpr_else {
return *args...;
}
}

现在这是一种替代方案。如果不同的分支返回不同的类型,它会变得更加复杂。

此外,

I must point out some things here:

  • I can return, break, continue and goto from within a constexpr if block. I can not do that from within the lambda.

  • While I am a big proponent of using lambdas to create new control facilities, I find the constexpr if solution infinitely more readable.

更进一步,

Richard Smith explained the following:

Right, when a function template is instantiated, all of the declarations/statements/expressions within it are instantiated, and that includes pieces inside local classes, generic lambdas, and so on.

This instantiation of generic lambda bodies is in fact necessary for our language semantics -- computing the captures of a generic lambda within a function template specialization relies on us having already instantiated the complete closure type and its call operator template to the point that we know where the odr-uses are within the non-dependent full-expressions within the body.

相比之下,constexpr if 的意图是不采取分支 未实例化。

关于c++ - 模仿 "if constexpr"行为,不可能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39125709/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com