這個問題在這里已經有了答案: 是否可以在標準 C 中列印變數的型別? (22 個回答) 17 天前關閉。
我正在使用包裝boost numeric_cast器函式撰寫一個包裝器,例如:
#include <boost/numeric/conversion/cast.hpp>
#include <stdexcept>
template <typename Source, typename Target>
Target numeric_cast(Source src)
{
try
{
// calling boost numeric_cast here
}
catch(boost::numeric::bad_numeric_cast& e)
{
throw std::runtime_error("numeric_cast failed, fromType: " Source " toType: " Target);
}
}
我有這個錯誤:
error: expected primary-expression before ‘(’ token
throw std::runtime_error("numeric_cast failed ...
^
我認為錯誤是要求處理Source并Target在錯誤訊息中。那么有沒有辦法列印template typename?我是 C 的初學者,所以這可能是一個愚蠢的問題......
uj5u.com熱心網友回復:
您可以使用typeid(T).name()來獲取模板引數的原始字串:
#include <boost/numeric/conversion/cast.hpp>
#include <stdexcept>
#include <typeinfo>
template <typename Source, typename Target>
Target numeric_cast(Source src)
{
try
{
// calling boost numeric_cast here
}
catch(boost::numeric::bad_numeric_cast& e)
{
throw (std::string("numeric_cast failed, fromType: ")
typeid(Source).name() " toType: " typeid(Target).name());
}
}
演示。
請注意,字串文字"numeric_cast failed, fromType:"應該是std::string支持' '運算子的型別。
uj5u.com熱心網友回復:
首先,您應該翻轉模板引數。Source可以自動推匯出另一方面Target不能。所以Target必須明確提供并且應該在模板引數串列中排在第一位,所以Source無論如何都可以推匯出來。
第二個問題是不能像那樣添加字串文字(這來自 C)。要在 C 中構建復雜的字串,請使用std::ostringstream.
要獲取型別名稱資訊,您可以使用typeid. 由于此名稱已被破壞并且您已經使用了boost,因此您可以使用該名稱來分解該名稱boost并獲得良好的人類可讀型別名稱。
最后一點:直接使用std::runtime_error是懶惰開發者的體現。為此類場景引入自己的例外類是一個很好的做法。
#include <iostream>
#include <sstream>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/core/demangle.hpp>
#include <typeinfo>
#include <stdexcept>
template<typename T>
std::string typeName()
{
return boost::core::demangle(typeid(T).name());
}
// this is used to bind all exceptions related to local library
class MyLibExceptions : public std::exception
{};
class BadNumericCast : public MyLibExceptions
{
public:
template<typename Target, typename Source>
BadNumericCast(Source arg, Target, const char *extra)
{
std::ostringstream desc;
desc << extra << " from type: '" << typeName<Source>()
<< "' with value: " << arg
<< " to type: '" << typeName<Target>() << '\'';
mDesc = desc.str();
}
const char* what() const noexcept override
{
return mDesc.c_str();
}
private:
std::string mDesc;
};
template <typename Target, typename Source>
Target numeric_cast(Source arg)
{
try
{
return boost::numeric::converter<Target, Source>::convert(arg);
}
catch(boost::numeric::bad_numeric_cast& e)
{
throw BadNumericCast{arg, Target{}, e.what()};
}
}
現場演示
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/333141.html
上一篇:如何使用元編程在C 中撰寫此函式
