decltype和成员函数(非指针)类型

Nub*_*ase 1 c++ decltype visual-c++ c++11 visual-c++-2012

struct C
{
    int Foo(int i) { return i; }

    typedef decltype(C::Foo) type;
};
Run Code Online (Sandbox Code Playgroud)

由于没有成员函数类型这样的类型(没有,有吗?),我希望C::type如此int (int).

但以下将无法使用Visual C++ 2012 RC进行编译:

std::function<C::type> f;
Run Code Online (Sandbox Code Playgroud)

那是什么类型的decltype(C::Foo)

Jam*_*lis 7

代码格式不正确:只有几种方法可以使用成员函数名称(例如C::Foo),而这不是其中之一(有效用法的完整列表可以在C++语言标准中找到,参见C++11§5.1.1/ 12).

在您的示例的上下文中,您唯一能做的就是获取成员函数的地址&C::Foo,以形成指向类型的成员函数的指针int (C::*)(int).

由于代码格式错误,编译器应该拒绝它.此外,根据C::Foo使用方式,它会产生不一致的结果; 我们将看看下面的不一致.

请报告Microsoft Connect上的错误.另外,请告诉我,我很乐意报告此问题.


如果您有类型但不知道类型是什么,则可以通过使用它来导致编译器发出错误的方式找出类型的名称.例如,声明一个类模板,从不定义它:

template <typename T>
struct tell_me_the_type;
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用您感兴趣的类型实例化此模板:

tell_me_the_type<decltype(C::Foo)> x;
Run Code Online (Sandbox Code Playgroud)

由于tell_me_the_type尚未定义,定义x无效.编译器应该T在它发出的错误中包含类型.Visual C++ 2012 RC报告:

error C2079: 'x' uses undefined struct 'tell_me_the_type_name<T>'
with
[
    T=int (int)
]
Run Code Online (Sandbox Code Playgroud)

编译器认为C::Foo是类型的int (int).如果是这种情况,那么编译器应该接受以下代码:

template <typename T>
struct is_the_type_right;

template <>
struct is_the_type_right<int(int)> { };

is_the_type_right<decltype(C::Foo)> x;
Run Code Online (Sandbox Code Playgroud)

编译器不接受此代码.它报告以下错误:

error C2079: 'x' uses undefined struct 'is_the_type_right<T>'
with
[
    T=int (int)
]
Run Code Online (Sandbox Code Playgroud)

因此,C::Foo两者都属于类型int (int),而不属于类型int (int),这违反了非矛盾原则.:-)