首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >decltype(函数)作为类成员

decltype(函数)作为类成员
EN

Stack Overflow用户
提问于 2012-02-17 18:38:54
回答 3查看 1.3K关注 0票数 6

我有:

代码语言:javascript
复制
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):

代码语言:javascript
复制
error: declaration of 'operator()' as non-function

将成员名称更改为

代码语言:javascript
复制
  decltype(foo) blubb;

使用它会导致链接器错误:

代码语言:javascript
复制
undefined reference to `Bar::blubb(int)'

这是预期的行为吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-02-17 21:12:00

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

如链接器错误所示:

代码语言:javascript
复制
undefined reference to `Bar::blubb(int)'

这在你的编译器中已经可以很好的工作了。然而,似乎gcc还没有完全实现标准的这一部分,因为它不会接受与函数调用运算符相同的语法。顺便说一句。将很高兴地接受它,然后这个链接就会错误地输出

代码语言:javascript
复制
undefined reference to `Bar::operator()(int)'

你关于为什么链接器错误存在的问题表明了对decltype真正作用的误解。

它只会计算出一个类型,而不是更多。blubb的定义与foo的定义没有任何关系。如果像这样写,这可能会更清楚

代码语言:javascript
复制
typedef decltype(foo) x; 
x blubb;

你现在也可以选择type x作为函数类型,这不会改变blubb是什么。你仍然需要给它下定义。而且由于没有使用decltype来定义它的语法,所以必须显式地将它写成

代码语言:javascript
复制
int Bar::operator()(int) {
...
}

不幸的是,这很可能与使用decltype声明的目的/好处背道而驰,因为它不允许自动“复制”签名。

票数 5
EN

Stack Overflow用户

发布于 2012-02-17 18:54:37

这是一个基于观察printf用法的胡乱猜测:

代码语言:javascript
复制
printf("%d\n",bar(6));

这让我假设您确实想要函数的返回类型,而不是函数的类型。如果是这样,那么您使用decltype是错误的。你可以通过“模拟”函数的使用来获得函数的返回类型。

代码语言:javascript
复制
decltype(foo(0)) operator() (int);

对你来说应该是正确的事情。否则,如果您没有注意到这一点,那么给%d说明符一个函数类型(而不是函数返回类型)是如履薄冰。

通常,decltype的含义是:decltype(@)给出了表达式@的静态类型。

票数 2
EN

Stack Overflow用户

发布于 2012-02-18 03:45:21

这应该是可行的。我只是在这里使用它来捕获std::bind将提供给我的任何内容:

代码语言:javascript
复制
class RiceFadingModel::Impl
{
public:
  Impl(double K, double A)
  : //...
    _M_re{system_now()},
    _M_rd{_M_nu, _M_sigma},
    _M_gen{std::bind(_M_rd, _M_re)}
  { }


private:

//...

  std::default_random_engine _M_re;
  ///  The underlying Rice distribution.
  __gnu_cxx::__rice_distribution<double> _M_rd;
  ///  The variate generator built from the pseudo-random number engine and the Rice distribution.
  decltype(std::bind(_M_rd, _M_re)) _M_gen;
};

这对gcc-4.7来说就像是一个护身符。现在我想了想,我也是用gcc-4.5在mingw上构建的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9326733

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档