在Boost模板参数中发现了C++奇怪的语法

Din*_*aiz 8 c++ boost functor boost-function

我正在浏览Boost中的"Function"类文档,并偶然发现:

boost::function<float (int x, int y)> f;
Run Code Online (Sandbox Code Playgroud)

我必须承认这种语法对我来说非常困惑.这怎么可能是合法的C++?

引擎盖下有什么伎俩吗?这种语法记录在何处?

sti*_*472 9

[编辑]这是对作者未经编辑的原始问题的回答,这个问题实际上是两个问题.

我必须承认这种语法对我来说非常困惑.这怎么可能是合法的C++?:)引擎盖下有什么伎俩吗?这种语法记录在何处?

这是完全合法的,实际上并不太复杂.

template <class T>
class C
{
public:
    T* function_pointer;
};

void fn(int x)
{
    cout << x << endl;
}

int main(int argc, char** argv)
{
    C<void (int x)> c;
    c.function_pointer = &fn;
    c.function_pointer(123); // outputs x
}
Run Code Online (Sandbox Code Playgroud)

它基本上和做的一样:

typedef void Function(int);
C<Function> c;
Run Code Online (Sandbox Code Playgroud)

这种类型不仅适用于C++,它也适用于C(实际类型C参数化).这里的模板魔法在这里采用类似函数typedef的东西,并且能够检测返回值和参数的类型.解释这里的篇幅太长了,boost :: function在boost中使用了很多函数traits元模板来检索那些信息.如果你真的想花时间学习这个,你应该尝试从Boost.Type Traits中的boost :: function_traits开始理解boost实现.

但是,我想解决您的一般问题.我认为你正在努力简化几行完全可以接受的代码.通过参数化的子类构造函数传递命令子类的参数没有错.是否真的值得尝试在这里涉及类型列表和boost :: function-like解决方案,从而显着增加编译时间和代码复杂性,仅此而已?

如果你想进一步减少它,只需编写一个执行任何命令子类的执行函数并将其添加到撤消堆栈中,依此类推:

typedef boost::shared_ptr<Command> CommandPtr;

void execute(const CommandPtr& cmd)
{
    cmd->execute();
    // add command to undo stack or whatever else you want to do
}

// The client can simply write something like this:
execute(CommandPtr(new CmdAdd(some_value) );
Run Code Online (Sandbox Code Playgroud)

我真的认为试图让它变得更复杂的权衡是不值得的.boost作者希望为boost :: function编写一个非常通用的解决方案,许多人将在许多平台和编译器中使用它.但是,他们没有尝试概括一个能够在统一的撤销系统中执行具有不同签名的功能的命令系统(从而要求即使在最初完成调用它们之后也能保留这些命令的状态并且能够撤消和重新执行 - 在不执行后续执行时重新指定原始状态数据的情况下执行它们.为此,基于继承的方法很可能是最好和最直接的方法.

  • `typedef float(int,int)命令`,我很遗憾地说,是不合法的C.正确的C代码是`typedef float Command(int,int)`.`typedef`采用常规声明,而不是定义命名对象(即函数或变量),它使用名称作为对象类型类型的别名. (2认同)