[英]Get the name of a time type in chrono
假設我有一個測量類的時間,可以通過這樣的持續時間類型進行參數化
template<typename TimeT = std::chrono::milliseconds>
struct measure
{ /* implementation */ };
我想要的是能夠打印出TimeT
。 我傾向於實現這樣的靜態成員函數:
static string TimeType() const;
我的問題是:
typeinfo / name
組合(在這種情況下我必須刪除上面的constexpr
)或者我應該選擇創建幾個特殊化,這些特殊化將返回每種時間類型的正確字符串? 歡迎您使用我的<chrono_io>
庫 。 它由一個標題"chrono_io.h"
,它在文檔中鏈接。 使用示例如下:
#include "chrono_io.h"
#include <iostream>
template<typename TimeT = std::chrono::milliseconds>
struct measure
{
TimeT value;
friend
std::ostream&
operator<< (std::ostream& os, const measure& m)
{
using namespace date;
return os << m.value;
}
};
int
main()
{
using namespace std::chrono;
measure<> m1 = {30ms};
std::cout << m1 << '\n';
measure<duration<int, std::ratio<1, 60>>> m2 = {duration<int, std::ratio<1, 60>>{45}};
std::cout << m2 << '\n';
}
哪個輸出:
30ms
45[1/60]s
一種方法是專注於時間類型; 這樣, typeid.name()
非可移植性就不再是一個因素:
/// get the name of the chrono time type
template<typename T> string time_type() { return "unknown"; }
template<> string time_type<std::chrono::nanoseconds >() { return "nanoseconds"; }
template<> string time_type<std::chrono::microseconds>() { return "microseconds"; }
template<> string time_type<std::chrono::milliseconds>() { return "milliseconds"; }
template<> string time_type<std::chrono::seconds >() { return "seconds"; }
template<> string time_type<std::chrono::minutes >() { return "minutes"; }
template<> string time_type<std::chrono::hours >() { return "hours"; }
這個q並沒有引起太多關注。 我發布了一個答案作為代碼質量比較的最小基礎
當然,這里的困難案例是在編譯時獲得這些信息,這需要編譯時字符串 n'的東西
上面的另一個版本是
template<class> struct time_type { constexpr static char const *name = "unknown"; };
template<> struct time_type<nanoseconds > { constexpr static char const *name = "nanoseconds"; };
template<> struct time_type<microseconds> { constexpr static char const *name = "microseconds"; };
template<> struct time_type<milliseconds> { constexpr static char const *name = "milliseconds"; };
template<> struct time_type<seconds > { constexpr static char const *name = "seconds"; };
template<> struct time_type<minutes > { constexpr static char const *name = "minutes"; };
template<> struct time_type<hours > { constexpr static char const *name = "hours"; };
duration
和time_point
都有一個類型為ratio
的period
成員,表示該類型的每個tick的秒數。
我不相信C ++標准提供了一種將10
特殊權力轉換為公制前綴的方法; 你必須為此推出自己的功能。 但請注意,這段時間不一定是標准時期; 用戶可以根據他們喜歡的任何時期(例如年)或甚至標准時段創建時間測量,但使用不同的表示類型(例如, double
),因此您可能不應該假設。 為什么不把它作為另一個參數?
您要做的是反射定義的一部分,更具體地說是運行時類型信息( RTTI ),它使代碼能夠在運行時自行檢查,我在嘗試制作時對此進行了很好的研究。將傳入類型的所有成員變量序列化為{ "varName"=<varValue> }
等格式的系統
不幸的是,簡單的答案是C ++本身不支持反射,並且它提供“類似”功能(即<type_traits>
和typeid()
),它還有很多不足之處。 最好的結果將來自生成您需要的數據的自定義構建步驟,我決定反對這種方法,因此在這種情況下無法真正幫助“如何”,但這些方法顯然在可移植性方面受到限制。
然而,您已經提到過的模板特化方法是邁向C ++運行時反射的最佳實現的一步,C ++運行時反射使用宏的組合來生成類描述符。
MFC宏DECLARE_DYNAMIC和IMPLEMENT_DYNAMIC是為您的類創建這些描述符之一所需的所有污染,然后添加函數IsKindOf()
, GetRuntimeClass()
等 ,最有用的通常是GetRuntimeClass()
,它返回CRuntimeClass
。
要實現類似的東西,你可以使用類似的東西;
#define MakeClassDescriptor(classname) \
private: \
class classname ## Descriptor \
{ \
public: \
static const char* GetName() { return #classname; } \
}; \
public: \
typedef classname ## Descriptor ClassDescriptor;
class Test
{
public:
Test() {};
MakeClassDescriptor(Test);
};
然后,這將允許您通過Test::ClassDescriptor::GetName()
訪問該名稱
當然還有其他方法和你自己的規范決定你如何實現這一點,對於一個類從模板化的RTTI類繼承的方法的例子,請查看由Dominic Filion在書中寫的文章“在C ++中使用模板反射”編程寶石5
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.