死代码消除是一种常见的优化。
但是,如果您根本不相信您的编译器会进行任何优化,您可以创建一个静态 iftemplate
库。
如果您不想阅读一堆非常可怕的黑客,请跳到妙语。
#include <utility>
#include <type_traits>
template<bool b>
struct static_if_t {
static_if_t( static_if_t const& ) = default;
static_if_t() = default;
static_if_t( static_if_t<b>(*)(std::integral_constant<bool,b>) ) {}
};
template<bool dead>
struct static_if_branch {};
template<bool b>
struct static_else_if_t {
static_else_if_t( static_else_if_t const& ) = default;
static_else_if_t() = default;
static_else_if_t( static_else_if_t<b>(*)(std::integral_constant<bool,b>) ) {}
};
template<bool b>
static_if_t<b> static_if(std::integral_constant<bool,b> unused=std::integral_constant<bool,b>()) {return {};}
template<bool b>
static_else_if_t<b> static_else_if(std::integral_constant<bool,b> unused=std::integral_constant<bool,b>()) {return {};}
static auto static_else = static_else_if<true>;
template<typename Lambda, typename=typename std::enable_if< std::is_same< decltype(std::declval<Lambda&&>()()), decltype(std::declval<Lambda&&>()()) >::value >::type>
static_if_branch<true> operator*( static_if_t<true>, Lambda&& closure )
{
std::forward<Lambda>(closure)();
return {};
}
template<typename Lambda, typename=typename std::enable_if< std::is_same< decltype(std::declval<Lambda&&>()()), decltype(std::declval<Lambda&&>()()) >::value >::type>
static_if_branch<false> operator*( static_if_t<false>, Lambda&& /*closure*/ )
{
return {};
}
template<typename Unused>
static_if_branch<true> operator*( static_if_branch<true>, Unused&& ) {
return {};
}
static_if_t< true > operator*( static_if_branch<false>, static_else_if_t<true> ) {
return {};
}
static_if_t< false > operator*( static_if_branch<false>, static_else_if_t<false> ) {
return {};
}
这是妙语:
#include <iostream>
int main() {
static_if<true>* [&]{
std::cout << "hello\n";
} *static_else* [&]{
std::cout << "doom\n";
};
static_if<false>* [&]{
std::cout << "doom the\n";
} *static_else* [&]{
std::cout << "world\n";
};
static_if<false>* [&]{
std::cout << "fello\n";
} *static_else_if<false>* [&]{
std::cout << "yellow\n";
} *static_else_if<false>* [&]{
std::cout << "hehe\n";
};
static_if( std::is_same<int, int>() )* [&]{
std::cout << "int is int\n";
};
static_if( std::is_same<double, double>() )* [&]{
std::cout << "double is double\n";
} *static_else_if( std::is_same<int, double>() )* [&]{
std::cout << "int is double\n";
} *static_else* [&]{
std::cout << "sky is not blue\n";
};
}
但你为什么要这样做? 活生生的例子
(请注意,上面有两种语法static_if
——一种static_if<compile time boolean expression>
,另一种static_if( std::is_whatever<blah>() )
)。
现在,虽然上面的内容完全是疯狂的,但上面的技术可以让你编写一个编译时三元运算符,它允许根据选择的分支选择不同的类型。这很整洁。
即,像这样:
auto result = trinary<std::is_same<A,B>::value>% 7 | 3.14;
并且类型result
将是int
如果A
和B
是相同类型,并且double
如果它们不同。甚至:
auto result = meta_trinary<std::is_same<A,B>::value>% [&]{return 7;} | [&]{return 3.14;};
如果您愿意,允许有条件地评估整个代码块,并存储返回值的条件类型。