我有一个相当老的应用程序,处理不同种类的货币。目前,货币存储在枚举中,例如:
enum CURRENCY {
EUR,
USD,
CNY
};
double convertMoney(CURRENCY in, CURRENCY out, double money_in) {
...
}
这非常有效,除了不是真正安全的类型:我还有其他包含注释的函数,例如
WARNING: all inputs should have the same currency
。我的目标是在可能的情况下通过编译时间检查来替换大多数这些注释。我可以使用C++ 17和boost。我想到使用
std::variant
这样的:class EUR {};
class USD {};
class CNY {};
using CURRENCY = std::variant<EUR,USD,CNY>;
template<typename IN, typename OUT>
class Market {
public:
...
double convertMoney(double in) {
return in*rate;
}
private:
void updateRate() {
....
rate = some_value_fetched_at_runtime;
}
double rate;
};
int main() {
Market<EUR, USD> eur_usd;
Market<EUR, CNY> eur_cny;
std::vector<Market<CURRENCY,CURRENCY>> all_markets{eur_usd, eur_cny};
...
//do something
...
return 0;
}
但是,当然,这将不起作用,因为我试图将不同类型的Market对象放入 vector 中。
因此,总而言之,你们认为替换现代C++中的枚举的最佳方法是什么?如果正确使用
std::variant
,解决上述问题的最佳方法是什么?注意:
using Markets = std::variant<Market<EUR,USD>,Market<EUR,CNY>,...>
的操作,但是实际上这是不可行的,因为我有大约100种类型的市场,并且这并不能真正改善可维护性。 CURRENCY
类,并具有EUR
的USD
,CNY
和CURRENCY
子类,但这将在运行时使用v-table,这将减少编译时检查的次数。如果有人能证明我是相反的话,我很乐意。 最佳答案
template< CURRENCY VCurrencyId > class
t_Sum
{
public: using
t_Value = double;
private: t_Value m_value{};
public:
t_Sum(void)
{}
public:
t_Sum(t_Sum const & other)
: m_value{other.m_value}
{}
public: explicit
t_Sum(t_Value const & value)
: m_value{value}
{}
public: t_Sum &
operator =(t_Sum const & other)
{
m_value = other.m_value;
return(*this);
}
public: t_Value const &
Get_Value(void)
{
return(m_value);
}
public: void
Set_Value(t_Value const & value)
{
m_value = value;
}
};
template< CURRENCY VInputCurrencyId, CURRENCY VOutputCurrencyId > t_Sum< VOutputCurrencyId >
Convert(t_Sum< VInputCurrencyId > in) {
...
}
using
t_Eur = t_Sum< EUR >;
using
t_Usd = t_Sum< USD >;
t_Eur euros{};
t_Usd bucks{euros};
// compile-time error, conversion required!
// or you can add converting constructor