【发布时间】:2014-06-13 13:19:39
【问题描述】:
我有许多类公开了一个名为Binding 的内部类型。例如,其中之一可能是:
struct Message
{
struct Binding
{
};
};
我像这样调用函数apply:
apply< Message >([](Message::Binding& x)
{
// setup binding fields
});
因为我写了
template <class TMessage, class TBindingExpression>
void apply(const TBindingExpression& expr)
{
typedef typename TMessage::Binding BindingType;
BindingType binding;
expr(binding);
apply(MessageUtil::typeId< TMessage >(), binding);
}
由于Message在我调用apply的方式上有点多余,我想让编译器推导出Message这样我就可以写了
apply([](Message::Binding x)
{
//...
});
到目前为止,我被困在这里:
template <class TBindingExpression>
void apply(const TBindingExpression& expr)
{
// I get the type of the argument which is Message::Binding in this example
typedef typename std::tuple_element
<
0,
FunctionTraits< TBindingExpression >::ArgumentTypes
>
::type BindingType;
// so I can invoke my expression
BindingType binding;
expr(binding);
// But now I need the type of the outer class, i.e. Message
typedef typename MessageTypeFromBinding< BindingType >::Type MessageType;
apply(MessageUtil::typeId< MessageType >(), binding);
}
有没有办法写/实现MessageTypeFromBinding?
显然,这纯粹是出于好奇和美观问题。
【问题讨论】:
-
IIRC 这是不可能的(类似于获取已声明类型的命名空间)。但是,您可以在
Binding中提供 typedef。此外,函数对象通常按值传递。依赖函数特征来获取operator()或类似的第一个参数的single 参数类型是危险的,考虑重载operator()甚至C++1y 的多态lambda。 -
@dyp:为什么使用我的
FunctionTraits获取单个参数的类型很危险? -
第二种类型的模板参数如何冗余?编译器应该如何知道
BindingType应该是什么类型,以及调用TBindingExpression时要调用什么重载? -
@misterwhy 因为它只适用于一小部分可调用实体。
-
在 c++14 中调用
apply< Message >([](auto& x) { // setup binding fields });消除了冗余。
标签: c++ templates metaprogramming