c++ std::enable_if ....否则?
c++ std::enable_if .... else?
#include <stdio.h>
#include <type_traits>
void print()
{
printf("cheers from print !\n");
}
class A
{
public:
void print()
{
printf("cheers from A !");
}
};
template<typename Function>
typename std::enable_if< std::is_function<
typename std::remove_pointer<Function>::type >::value,
void >::type
run(Function f)
{
f();
}
template<typename T>
typename std::enable_if< !std::is_function<
typename std::remove_pointer<T>::type >::value,
void >::type
run(T& t)
{
t.print();
}
int main()
{
run(print);
A a;
run(a);
return 0;
}
上面的代码按预期编译和打印:
cheers from print ! cheers from A !
我想表达的是:"if the template is function then apply this function, else ..."。或者换一种说法:函数模板有一个函数版本,非函数模板有一个默认版本。
所以,这部分似乎有点多余,并且可以 "replaced" 由 "else" 条件 :
template<typename T>
typename std::enable_if< !std::is_function<
typename std::remove_pointer<T>::type >::value,
void >::type
run(T& t)
这会存在吗?
您要找的是constexpr if。那会让你写出像
这样的代码
template<typename Obj>
void run(Obj o)
{
if constexpr (std::is_function_v<std::remove_pointer_t<Obj>>)
o();
else
o.print();
}
如果您不能访问 C++17 但有 C++14,您至少可以使用 variable template 缩短您需要编写的代码。那看起来像
template<typename T>
static constexpr bool is_function_v = std::is_function< typename std::remove_pointer<T>::type >::value;
template<typename Function>
typename std::enable_if< is_function_v<Function>, void>::type
run(Function f)
{
f();
}
template<typename T>
typename std::enable_if< !is_function_v<T>, void>::type
run(T& t)
{
t.print();
}
如果您仅限于使用 C++11,则可以使用标记分派机制。
namespace detail
{
template<typename Function>
void run(std::true_type, Function& f)
{
f();
}
template<typename Object>
void run(std::false_type, Object& o)
{
o.print();
}
} // namespace detail
template<typename T>
void run(T& t)
{
constexpr bool t_is_a_function =
std::is_function<typename std::remove_pointer<T>::type >::value;
using tag = std::integral_constant<bool, t_is_a_function>;
detail::run(tag{}, t);
}
#include <stdio.h>
#include <type_traits>
void print()
{
printf("cheers from print !\n");
}
class A
{
public:
void print()
{
printf("cheers from A !");
}
};
template<typename Function>
typename std::enable_if< std::is_function<
typename std::remove_pointer<Function>::type >::value,
void >::type
run(Function f)
{
f();
}
template<typename T>
typename std::enable_if< !std::is_function<
typename std::remove_pointer<T>::type >::value,
void >::type
run(T& t)
{
t.print();
}
int main()
{
run(print);
A a;
run(a);
return 0;
}
上面的代码按预期编译和打印:
cheers from print ! cheers from A !
我想表达的是:"if the template is function then apply this function, else ..."。或者换一种说法:函数模板有一个函数版本,非函数模板有一个默认版本。
所以,这部分似乎有点多余,并且可以 "replaced" 由 "else" 条件 :
template<typename T>
typename std::enable_if< !std::is_function<
typename std::remove_pointer<T>::type >::value,
void >::type
run(T& t)
这会存在吗?
您要找的是constexpr if。那会让你写出像
这样的代码template<typename Obj>
void run(Obj o)
{
if constexpr (std::is_function_v<std::remove_pointer_t<Obj>>)
o();
else
o.print();
}
如果您不能访问 C++17 但有 C++14,您至少可以使用 variable template 缩短您需要编写的代码。那看起来像
template<typename T>
static constexpr bool is_function_v = std::is_function< typename std::remove_pointer<T>::type >::value;
template<typename Function>
typename std::enable_if< is_function_v<Function>, void>::type
run(Function f)
{
f();
}
template<typename T>
typename std::enable_if< !is_function_v<T>, void>::type
run(T& t)
{
t.print();
}
如果您仅限于使用 C++11,则可以使用标记分派机制。
namespace detail
{
template<typename Function>
void run(std::true_type, Function& f)
{
f();
}
template<typename Object>
void run(std::false_type, Object& o)
{
o.print();
}
} // namespace detail
template<typename T>
void run(T& t)
{
constexpr bool t_is_a_function =
std::is_function<typename std::remove_pointer<T>::type >::value;
using tag = std::integral_constant<bool, t_is_a_function>;
detail::run(tag{}, t);
}