以下代码可以编译并运行:
预期输出(所有支持的平台):
但是我遇到了这个错误:
#include <cinttypes>
#include <cstdlib>
#include <iostream>
#include <limits>
#include <sstream>
#include <stdexcept>
class UnsignedBox {
public:
typedef std::uint64_t box_type;
template<typename UNSIGNED_TYPE,
typename std::enable_if<
std::numeric_limits<UNSIGNED_TYPE>::is_signed==false &&
(sizeof(UNSIGNED_TYPE) >= sizeof(UnsignedBox::box_type)), int>::type = 0
>
UNSIGNED_TYPE toUnsigned()const {
//We've established we're not returning a smaller type so we can just
//return our value.
return value;
}
template<typename UNSIGNED_TYPE,
typename std::enable_if<std::numeric_limits<UNSIGNED_TYPE>::is_signed==false &&
(sizeof(UNSIGNED_TYPE) < sizeof(UnsignedBox::box_type)), int>::type = 0
>
UNSIGNED_TYPE toUnsigned()const {
//We are returning a smaller type so we need a range check.
if(value>static_cast<box_type>(std::numeric_limits<UNSIGNED_TYPE>::max())){
std::ostringstream msg;
msg<<value<<'>'<<
static_cast<box_type>(std::numeric_limits<UNSIGNED_TYPE>::max());
throw std::logic_error(msg.str());
}
return value;
}
UnsignedBox(const box_type ivalue): value(ivalue){}
private:
box_type value;
};
int main(int argc, char*argv[]) {
UnsignedBox box(
static_cast<UnsignedBox::box_type>(
std::numeric_limits<std::uint32_t>::max())+10
);
std::uint64_t v(box.toUnsigned<std::uint64_t>());
std::cout<<v<<std::endl;
try {
std::uint32_t v(box.toUnsigned<std::uint32_t>());
}catch(const std::logic_error err){
std::cout<<err.what()<<std::endl;
}
return EXIT_SUCCESS;
}
预期输出(所有支持的平台):
4294967305
4294967305>4294967295
到目前为止都很顺利。
但是我真正想做的(为了代码清晰):
是声明类似于:
template<typename UNSIGNED_TYPE>
UNSIGNED_TYPE toUnsigned()const;
接下来提供专业的实现,例如:
template<typename UNSIGNED_TYPE,
typename std::enable_if<
std::numeric_limits<UNSIGNED_TYPE>::is_signed==false &&
(sizeof(UNSIGNED_TYPE) >= sizeof(UnsignedBox::box_type)), int>::type = 0
>
UNSIGNED_TYPE UnsignedBox::toUnsigned()const {
//We've established we're not returning a smaller type so we can just
//return our value.
return value;
}
template<typename UNSIGNED_TYPE,
typename std::enable_if<std::numeric_limits<UNSIGNED_TYPE>::is_signed==false &&
(sizeof(UNSIGNED_TYPE) < sizeof(UnsignedBox::box_type)), int>::type = 0
>
UNSIGNED_TYPE UnsignedBox::toUnsigned()const {
//We are returning a smaller type so we need a range check.
if(value>static_cast<box_type>(std::numeric_limits<UNSIGNED_TYPE>::max())){
std::ostringstream msg;
msg<<value<<'>'<<
static_cast<box_type>(std::numeric_limits<UNSIGNED_TYPE>::max());
throw std::logic_error(msg.str());
}
return value;
}
但是我遇到了这个错误:
xxx.cpp:nn:20: error: prototype for 'UNSIGNED_TYPE UnsignedBox::toUnsigned() const' does not match any in class 'UnsignedBox'
UNSIGNED_TYPE UnsignedBox::toUnsigned()const {
^ xxx.cpp:nn:23: error: candidate is: template<class UNSIGNED_TYPE> UNSIGNED_TYPE UnsignedBox::toUnsigned() const
UNSIGNED_TYPE toUnsigned()const;
^
这很奇怪,因为如果你问我原型的定义,
UNSIGNED_TYPE UnsignedBox::toUnsigned() const
对于IT技术而言,这是一个非常合适的组合。
UNSIGNED_TYPE toUnsigned()const;
我做错了什么?
附言:这不是实际问题,但我的问题类似,我想基于编译时检查的原始类型属性来特殊处理一些模板。
std::is_unsigned
特性,可能比使用std::numeric_limits
类更合适。 - davidhigh