如何使用 std::is_integral<> 选择实现?
How do I use std::is_integral<> to select an implementation?
如果std::is_integral<>::value
为真,我试图返回int64_t
。
否则,我想对对象调用to_int64t()
。
我下面的尝试失败了,因为函数模板的部分专门化是不允许的。
#include <type_traits>
#include <cstdint>
template<class T,bool is_integral_type>
int64_t to_int64t( const T& t )
{
return t;
}
template<class T>
int64_t to_int64t<T,std::is_integral<T>::value>( const T& t )
{
return t;
}
template<class T>
int64_t to_int64t<T,!std::is_integral<T>::value>( const T& t )
{
return t.to_int64t();
}
int main()
{
int64_t i = 64;
auto x = to_int64t( i );
}
函数模板不能部分特化,一般来说,使用函数模板特化不是一个好主意。
实现您想要的一种方法是使用一种称为标记调度的技术,它基本上包括提供一个转发器函数,该函数根据额外的虚拟参数的值选择正确的过载:#include <type_traits>
#include <cstdint>
template<class T>
int64_t to_int64t( const T& t, std::true_type )
{
return t;
}
template<class T>
int64_t to_int64t( const T& t, std::false_type )
{
return t.to_int64t();
}
template<class T>
int64_t to_int64t( const T& t )
{
return to_int64t(t, std::is_integral<T>());
}
int main()
{
int64_t i = 64;
auto x = to_int64t( i );
}
另一种可能性是使用基于std::enable_if
的经典SFINAE技术。这就是它的样子(注意,从c++ 11开始,函数模板上的默认模板参数是允许的):
#include <type_traits>
#include <cstdint>
template<class T, typename std::enable_if<
std::is_integral<T>::value>::type* = nullptr>
int64_t to_int64t( const T& t )
{
return t;
}
template<class T, typename std::enable_if<
!std::is_integral<T>::value>::type* = nullptr>
int64_t to_int64t( const T& t )
{
return t.to_int64t();
}
int main()
{
int64_t i = 64;
auto x = to_int64t( i );
}
另一种可能性,虽然更冗长,是在detail
名称空间中定义助手类模板(可以部分专门化)并提供全局转发器——我不会在这个用例中使用这种技术,但我展示它是因为它可能在相关的设计情况下很方便:
#include <type_traits>
#include <cstdint>
namespace detail
{
template<class T, bool = std::is_integral<T>::value>
struct helper { };
template<class T>
struct helper<T, true>
{
static int64_t to_int64t( const T& t )
{
return t;
}
};
template<class T>
struct helper<T, false>
{
static int64_t to_int64t( const T& t )
{
return t.to_int64t();
}
};
}
template<class T>
int64_t to_int64t( const T& t )
{
return detail::helper<T>::to_int64t(t);
}
int main()
{
int64_t i = 64;
auto x = to_int64t( i );
}
你可以直接使用std::enable_if
:
template<class T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
int64_t to_int64t( const T& t )
{
return t;
}
template<class T, typename std::enable_if<!std::is_integral<T>::value, int>::type = 0>
int64_t to_int64t( const T& t )
{
return t.to_int64t();
}
相关文章:
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 用于AVX的ln(x)的实现,m256
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- EASTL矢量<向量<int>>连续的
- 在C++中,如何在类和函数(可能是模板化的)的头中编写完整的实现