我有:
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将成员名称更改为
decltype(foo) blubb;使用它会导致链接器错误:
undefined reference to `Bar::blubb(int)'这是预期的行为吗?
发布于 2012-02-17 21:12:00
看起来你想“复制”另一个函数的签名来创建一个具有相同签名的函数。由于decltype(foo)确实是函数的类型(而不是指向该函数的指针,后者将是decltype(&foo),并会导致指针声明),因此可以使用它来声明一个与另一个函数具有相同签名的函数。
如链接器错误所示:
undefined reference to `Bar::blubb(int)'这在你的编译器中已经可以很好的工作了。然而,似乎gcc还没有完全实现标准的这一部分,因为它不会接受与函数调用运算符相同的语法。顺便说一句。将很高兴地接受它,然后这个链接就会错误地输出
undefined reference to `Bar::operator()(int)'你关于为什么链接器错误存在的问题表明了对decltype真正作用的误解。
它只会计算出一个类型,而不是更多。blubb的定义与foo的定义没有任何关系。如果像这样写,这可能会更清楚
typedef decltype(foo) x;
x blubb;你现在也可以选择type x作为函数类型,这不会改变blubb是什么。你仍然需要给它下定义。而且由于没有使用decltype来定义它的语法,所以必须显式地将它写成
int Bar::operator()(int) {
...
}不幸的是,这很可能与使用decltype声明的目的/好处背道而驰,因为它不允许自动“复制”签名。
发布于 2012-02-17 18:54:37
这是一个基于观察printf用法的胡乱猜测:
printf("%d\n",bar(6));这让我假设您确实想要函数的返回类型,而不是函数的类型。如果是这样,那么您使用decltype是错误的。你可以通过“模拟”函数的使用来获得函数的返回类型。
decltype(foo(0)) operator() (int);对你来说应该是正确的事情。否则,如果您没有注意到这一点,那么给%d说明符一个函数类型(而不是函数返回类型)是如履薄冰。
通常,decltype的含义是:decltype(@)给出了表达式@的静态类型。
发布于 2012-02-18 03:45:21
这应该是可行的。我只是在这里使用它来捕获std::bind将提供给我的任何内容:
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上构建的。
https://stackoverflow.com/questions/9326733
复制相似问题