下面的代碼編譯和運行:模板與專業化的std :: enable_if <>
#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
原型這是奇怪的是
UNSIGNED_TYPE toUnsigned()const;
什麼我做錯了一場偉大的比賽?
PS:這不是實際的問題,但我的問題是一個類似的地方,我想根據在編譯時檢查的基本類型的屬性特定一些模板。
注意:還有一個'std :: is_unsigned'特徵可能比使用'std :: numeric_limits'類更合適。 – davidhigh