我有:
unarchive
采用字典和密钥并基于传递的模板类型(T
)可以专门生成T
struct
的构造函数,它利用unarchive
构建其成员示例可能如下:
template <typename T>
T unarchive(const dictionary_t&, key_type key);
struct foo
{
foo(const dictionary& archive) :
value_m(unarchive<decltype(value_m)>(archive, value_key))
{ }
some_value_type value_m;
};
这里使用unarchive<decltype(value_m)>
的好处是我可以更改value_m
的类型而无需更新这行代码 - 类型始终遵循成员变量的类型。
我遇到的问题更具审美性:它非常冗长。目前我有一个宏:
#define UNARCHIVE_FOR(var) unarchive<decltype(var)>
foo
的构造函数更改如下:
foo(const dictionary& archive) :
value_m(UNARCHIVE_FOR(value_m)(archive, value_key))
{ }
现在我有一个更简洁但更丑陋的结果。没有宏可以实现相同的结果吗?我想要的是类似的东西:
foo(const dictionary& archive) :
value_m(unarchive<value_m>(archive, value_key))
{ }
如何做到这一点?
答案 0 :(得分:4)
在这里使用unarchive的优点是我可以更改value_m的类型而无需更新这行代码 - 类型始终遵循成员变量的类型。
另一种方法是为value_m
类型创建一个别名,并从构造函数初始化列表中删除decltype(value_m)
:
struct foo
{
using value_type = int;
foo(const dictionary_t& archive, const key_type value_key) :
value_m(unarchive<value_type>(archive, value_key))
{ }
value_type value_m;
};
unarchive<value_type>
仍然遵循value_m
的类型。可以添加static_assert
以确保value_m
的类型与value_type
相同,如果担心value_m
的类型发生更改而不更改value_type
}}:
static_assert(std::is_same<decltype(value_m), value_type>::value,
"'value_m' type differs from 'value_type'");
或根据value_m
:
int value_m;
using value_type = decltype(value_m);
如果你仍然考虑构造函数初始化列表verbose提供一个调用static
函数的unarchive()
包装函数:
struct foo
{
using value_type = int;
foo(const dictionary_t& archive, const key_type value_key) :
value_m(unarchive_(archive, value_key))
{ }
static value_type unarchive_(const dictionary_t& d, key_type k)
{
return unarchive<value_type>(d, k);
}
value_type value_m;
};
说完了所有这些:
value_m(unarchive<decltype(value_m)>(archive, value_key))
并不是那么冗长,而且恰恰表达了意图。
答案 1 :(得分:1)
这有点像hackish,但如何使用模板化转换运算符为归档引入包装类:
class wrapper {
const dictionary_t& dict_m;
const key_type key_m;
public:
wrapper(const dictionary_t& d, key_type k) :
dict_m(d), key_m(k) {}
template <class T> operator T () const {
return unarchive<T>(dict_m, key_m);
}
};
所以你可以用:
进行初始化foo(const dictionary_t& archive, const key_type value_key) :
value_m(wrapper(archive, value_key))
{}