【发布时间】:2014-02-27 06:36:01
【问题描述】:
我正在尝试找到一种优雅的方式来实现类似非常简单的boost::mpl 类型映射。
在我的上下文中,使用 MPL 或任何其他 boost 库不是一个选项。此外,我真正需要的唯一操作是初始化和查找。存储编译时值也很好(如果我使用基于boost 的解决方案,我可以使用boost::fusion::set 来做到这一点)。
我知道如何使用特征类做我想做的事,但我认为语法有点过于冗长,并且还有一些其他的小缺点,例如你不能在类声明中定义特征特化,而且,通常它不会整齐地放在一个地方。
这是我想要使用特征实现的目标:
// base class definitions
class Foo {};
class Bar {};
class Baz {};
// traits base
template<typename T>
struct MyTraits {};
// traits specializations
template<>
struct MyTraits<Foo> {
static constexpr const char* name = "foo";
typedef double type;
};
template<>
struct MyTraits<Bar> {
static constexpr const char* name = "bar";
typedef std::string type;
};
// generic worker function
template<typename T>
void doStuff(const T& arg) {
std::cout << "got a " << MyTraits<T>::name << " - size: " << sizeof(typename MyTraits<T>::type) << std::endl;
}
int main(int, char*[]) {
Foo foo;
Bar bar;
Baz baz;
doStuff(foo);
doStuff(bar);
// this fails, as expected:
//doStuff(baz);
}
这是我希望能够使用的语法:
typedef TMapTemplate<
TMapEntry<Foo, double, "foo">,
TMapEntry<Bar, string, "bar">
> tTraitsMap;
// generic worker function
template<typename T>
void doStuff(const T& arg) {
std::cout << "got a " << at<tTraitsMap,T>::value<1>() << " - size: " << sizeof(at<tTraitsMap,T>::type<0>) << std::endl;
}
(这样的东西会很理想,但我会很高兴有一个简单的一对一类型映射,真的)
【问题讨论】:
-
如果你不能使用 Boost,你将如何使用
fusion::set? -
@TemplateRex: 我不会使用融合... @ 解决类型到值的问题(因为
mpl没有提供)。进行了相应的编辑以澄清 -
只是好奇,为什么不能为此使用 Boost?假设您将使用bcp tool 从
boost::mpl::map中提取所有依赖项,这会构成库解决方案还是您自己的私有代码? -
@TemplateRex:这个 issue 出现的项目有严格的库控制政策,
boost是禁区。我想如果需要,我可以按照您的建议提取相关代码,并且可以接受。在实践中,特质类可以很好地满足我们的需求,所以我的问题的实际方面到此结束。但是,我一直认为这种映射不会太难用新的 C++11 语言结构(如可变参数模板、元组等)来表达,所以这更像是一个风格练习题。
标签: c++ templates c++11 map boost-mpl