mercredi 24 août 2016

mimic "if constexpr" behavior

My compiler doesn't support if constexpr, but I am captivated by its benefit.
I must have it even it is a fake one.

This code is my attempt to mimic if constexpr behavior, I want to make the lines (###) appear in only 1 function :-

#include <iostream>
using namespace std;

template<bool T_wantRef,typename F> constexpr typename std::enable_if<!T_wantRef, void>::type iter_(F f,int i1){
    f(i1);
}
template<bool T_wantRef,typename F> constexpr typename std::enable_if<T_wantRef, void>::type iter_(F f,int i1){ }
template<bool T_wantRef,typename F> constexpr typename std::enable_if<T_wantRef, void>::type iter_(F f,int i1,int i2){
    f(i1,i2);
}
template<bool T_wantRef,typename F> constexpr typename std::enable_if<!T_wantRef, void>::type iter_(F f,int i1,int i2){}

template<bool T_wantRef,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 appear here, but omited
        if(T_wantRef){//mimic constexpr ?
            iter_<true>(f,1,2);
        }else{
            iter_<false>(f,3);
        }
    }
}

This is its usage:-

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;
}

I got compile error :

prog.cpp: In instantiation of 'constexpr typename std::enable_if<T_wantRef, void>::type iter_(F, int, int) [with bool T_wantRef = true; F = main()::<lambda(int)>; typename std::enable_if<T_wantRef, void>::type = void]':
prog.cpp:16:18:   required from 'constexpr void fff(F) [with bool T_wantRef = 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

From the error, it is clear that even the function has std::enable_if[ effective FALSE],
the compiler still compiled code that inside the function. - That is bad.

Which parts do I have to edit?
Or is it impossible to mimic if constexpr (that is the reason why it is introduced finally)?

Aucun commentaire:

Enregistrer un commentaire