- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我的编译器不支持 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/
在 ubuntu gcc 8.0 中: void bar(){} constexpr int foo(int a) { if (a <=0 ) bar(); retur
考虑一个在运行时只包装一个值的类: template class NonConstValue { public: NonConstValue(const Type& val)
在试验 constexpr 函数和模板(以及非类型模板参数)时,我偶然发现了一个现象,我无法理解是哪条规则使它生效。 所以根据 constexpr-s 的规则,我的问题本质上是“为什么会发生这种情况”
我正在阅读 Nicolai M. Josuttis 所著的“C++ 17 The Complete Guide”一书,无法理解以下示例 auto squared1 = [](auto val) con
(使用 g++ 7.0 主干。) 给定以下“类型到值包装”实用程序... template struct type_wrapper { using type = T; }; // "Wraps" a
我编写了一些代码,它能够根据调用站点提供与给定函数关联的字符串(通过函数指针和并行数组的tuple)来分派(dispatch)给函数。 dispatch 函数不直接接受字符串,而是接受 Callabl
如果我想使用一些方便的东西,比如 make_array 我没有机会先声明我的数组,然后再像“早些时候”那样进行定义,因为我的 var 类型不可用定义前。 所以我找到了这个答案: Undefined r
使用 gcc (HEAD 7.0.0 201612) 我惊讶地发现这有效: constexpr long value(const char *definition) { if (definit
我有这个片段。 #include #include struct JustStr { JustStr(const std::string& x) : val(x) {} stati
我找不到任何关于新 C++17 if 初始化语法的信息和“constexpr if”在: http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p01
考虑以下函数: template auto concatenate(std::array &data1, std::array &data2) { std::array result;
假设我有以下对象: #include class Foo { public: constexpr Foo() {}; constexpr std::string foo() cons
我正在尝试使用 https://github.com/gdelugre/literal_ipaddr它说它是一个 C++17 constexpr implementation of inet_addr
我想重新定义unique_ptr用一个特殊的析构函数。因此,我使用以下代码尝试模仿 unique_ptr 的一些构造函数.遗憾constexpr施 worker 员拒绝 build ,我不知道为什么。
我想用结构名称的哈希值初始化一个结构成员。 constexpr uint32_t myHash(const char* const data) { //Some code for hash r
我正在尝试编译 C++ 库(使用 gcc 5.3.1-14ubuntu2)并遇到此类错误: > In file included from > /root/pitchfork/workspace/un
设置: 我有一个使用 SIMD 内部函数的函数,我想在一些 constexpr 函数中使用它。 为此,我需要将其设为 constexpr。但是,SIMD 内在函数没有标记为 constexpr,编译器
这是一个简化的代码示例,旨在生成任意值序列(在 std::iota 的意义上)和在它们之上的不同类别的迭代器: struct delta { template void inc(I&
考虑以下函数: template auto concatenate(std::array &data1, std::array &data2) { std::array result;
我偶然发现了调用非 constexpr 函数的 constexpr 模板函数:在以下代码段中,由于调用了非 constexpr set,bar 无法按预期编译,但 foo 可以编译。谁能告诉我 foo
我是一名优秀的程序员,十分优秀!