如何在编译时评估 Primitive 与 Class 模板?
How to evaluate Primitive vs Class templates at compilation time?
当我们做...
template <typename T>
void foo(T x)
{
if (is_fundamental<T>::value)
{
...
} else
{
...
}
}
我认为 if
语句(以及 is_fundamental<T>::value
)是在 运行 时计算的,对吗?
如果是,有没有办法在编译时进行这个评估?我想要类似...
template <primitive_typename T>
void foo(T x)
{
...
}
template <noPrimitive_typename T>
void foo(T x)
{
...
}
一个解决方案是重载所有可能的原始类型,但这并不是一个真正令人满意的解决方案,因为它需要多次复制原始类型的代码。有没有办法用一个类型名来引用所有基元?
标签调度呢?
template <typename T>
void fooHelper (T t, std::true_type const &)
{ /* true case */ }
template <typename T>
void fooHelper (T t, std::false_type const &)
{ /* false case */ }
template <typename T>
void foo (T t)
{ fooHelper(t, std::is_fundamental<T>{}); }
在 C++17 中,if constexpr
语句在编译时评估条件并丢弃未选择的分支:
if constexpr(std::is_fundamental_v<T>) {
// do something with x
} else {
// do something else with x
}
一种老式的方法是使用标签分派:
template <typename FundamentalType>
void foo_helper(FundamentalType x, std::true_type);
template <typename NonFundamentalType>
void foo_helper(NonFundamentalType x, std::false_type);
template <typename T>
void foo(T x) {
foo_helper(x, std::is_fundamental<T>{});
}
您也可以使用部分专用的帮助程序结构,但需要更多代码。
当我们做...
template <typename T>
void foo(T x)
{
if (is_fundamental<T>::value)
{
...
} else
{
...
}
}
我认为 if
语句(以及 is_fundamental<T>::value
)是在 运行 时计算的,对吗?
如果是,有没有办法在编译时进行这个评估?我想要类似...
template <primitive_typename T>
void foo(T x)
{
...
}
template <noPrimitive_typename T>
void foo(T x)
{
...
}
一个解决方案是重载所有可能的原始类型,但这并不是一个真正令人满意的解决方案,因为它需要多次复制原始类型的代码。有没有办法用一个类型名来引用所有基元?
标签调度呢?
template <typename T>
void fooHelper (T t, std::true_type const &)
{ /* true case */ }
template <typename T>
void fooHelper (T t, std::false_type const &)
{ /* false case */ }
template <typename T>
void foo (T t)
{ fooHelper(t, std::is_fundamental<T>{}); }
在 C++17 中,if constexpr
语句在编译时评估条件并丢弃未选择的分支:
if constexpr(std::is_fundamental_v<T>) {
// do something with x
} else {
// do something else with x
}
一种老式的方法是使用标签分派:
template <typename FundamentalType>
void foo_helper(FundamentalType x, std::true_type);
template <typename NonFundamentalType>
void foo_helper(NonFundamentalType x, std::false_type);
template <typename T>
void foo(T x) {
foo_helper(x, std::is_fundamental<T>{});
}
您也可以使用部分专用的帮助程序结构,但需要更多代码。