我希望有一些编译时间。但是我不能把if语句放入,因为编译器会检查两个分支,其中一个分支可能无效(在这种情况下调用不存在函数等等。)。
换句话说,我想要#ifdef
,但在模板中。 Consider helper/wrapper of this。所以,我编写了以下模板化的类,它期望bool参数。 "真"专业化调用一个函数," false" - 另一个:
#define MAKE_IF(c_name, fn1, fn2)\
template<bool select, class DUMMY = void>\
struct c_name{\
}; \
\
template<class DUMMY>\
struct c_name<true, DUMMY>{\
template<typename SELF, typename ...Args>\
static auto fire(SELF &&self, Args &&...args)-> decltype( self.fn1(std::forward<Args>(args)...) ){\
return self.fn1( std::forward<Args>(args)... );\
}\
};\
\
template<class DUMMY>\
struct c_name<false, DUMMY>{\
template<typename SELF, typename ...Args>\
static auto fire(SELF &&self, Args &&...args) -> decltype( self.fn2(std::forward<Args>(args)...) ) {\
return self.fn2( std::forward<Args>(args)...);\
}\
};
/// Usage:
MAKE_IF(selector, fn1, fn2 )
selector<do_it>::fire(*this);
一切顺利,一切顺利。但是我想摆脱这个#define
,所以我做了以下的事情(基于lambda):
template<bool select, class DUMMY = void>
struct CONDITION_HELPER{};
template<class DUMMY>
struct CONDITION_HELPER<true, DUMMY>{
template<class FN1, class FN2>
static auto fire(FN1 &&fn1, FN2 &&) -> decltype( fn1() ){
return fn1();
}
};
template<class DUMMY>
struct CONDITION_HELPER<false, DUMMY>{
template<class FN1, class FN2>
static auto fire(FN1 &&, FN2 &&fn2) -> decltype( fn2() ){
return fn2();
}
};
template<bool first, class FN1, class FN2>
auto if_else(FN1 &&fn1, FN2 &&fn2) -> decltype(
CONDITION_HELPER<first>::fire(
std::forward<FN1>(fn1),
std::forward<FN2>(fn2)
)
){
return CONDITION_HELPER<first>::fire(
std::forward<FN1>(fn1),
std::forward<FN2>(fn2)
);
}
//Usage:
if_else<do_it>(
[&]{ return fn1(data); },
[&]{ return fn2(data); }
);
这不起作用。在lambda的行上我得到了错误
main.cpp:111:37: error: non-const lvalue reference to type 'B' cannot bind to a value of unrelated type 'A'
[&]{ return fn1(data); },
完整代码: