我有:

int foo(int x) { return x+1; }

struct Bar {
  decltype(foo) operator();
};

int main() {
  Bar bar;
  printf("%d\n",bar(6));
}

这会导致稍微令人吃惊的编译器错误消息(g++ 4.6.1):
error: declaration of 'operator()' as non-function

将成员(member)名称更改为
  decltype(foo) blubb;

并使用它会导致链接器错误:
undefined reference to `Bar::blubb(int)'

这是预期的行为吗?

最佳答案

似乎您想“复制”另一个函数的签名以创建具有相同签名的函数。由于decltype(foo)确实是函数的类型(而不是指向该函数的指针,该指针将是decltype(&foo)并导致指针声明),因此可以使用它来声明具有与另一个函数相同签名的函数。

如链接器错误所示:

undefined reference to `Bar::blubb(int)'

这已经可以在您的编译器上正常工作了。但是,gcc似乎尚未完全实现标准的这一部分,因为它不会接受函数调用运算符对同一事物的语法。 clang 会很乐意接受它,然后链接就会出错
undefined reference to `Bar::operator()(int)'

您关于为何存在链接器错误的问题表明对decltype的实际作用有误解。

它只会计算一个类型,而不是更多。 blubb的定义与foo的定义没有任何关系。像这样写时可能会更清楚
typedef decltype(foo) x;
x blubb;

现在,您可以选择将typedef x显式指定为函数类型,而这绝不会改变blubb的含义。您仍然需要定义它。并且由于没有语法可以使用decltype进行定义,因此您必须明确地将其编写为
int Bar::operator()(int) {
...
}

这样做很可能会不幸地使使用decltype进行声明的目的/好处无效,因为它不允许您自动“复制”签名。

关于c++ - decltype(function)作为类成员,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9326733/

10-13 03:00