为什么这个公共成员函数不能在类中声明的私有struct成员上调用decltype?

时间:2013-09-21 05:59:12

标签: c++ visual-studio c++11 decltype visual-studio-2013

以下代码松散地表示我正在处理的一些序列化内容,使用g ++(http://ideone.com/0rsGmt)编译,但Visual Studio Express 2013 RC失败并出现以下错误:

Error 1 error C2326: 'void foo::print(void)' : function cannot access 'foo::bar::member_'
Error 2 error C2039: 'bar' : is not a member of 'foo'

代码:

#include <iostream>

class foo
{   
    private:
        struct bar
        {
            int member_;
        };

    public:
        void print()
        {
            std::cout << sizeof(decltype(foo::bar::member_)) << std::endl;
        }
};

int main(int argc, char* argv[])
{
    foo f;
    f.print();
    return 0;
}

怎么了? Visual Studio不足还是其他什么?显然我可以将struct声明移出类;丹尼尔弗雷在下面提供了一个解决方法;但是我想知道为什么上面的代码不会像Visual Studio一样编译。

更新:已接受的答案表明它应该可以正常运行,但对于微软来说却不然。我在这里填写了一个错误报告:http://connect.microsoft.com/VisualStudio/feedback/details/801829/incomplete-decltype-support-in-c-11-compiler

(如果有人能为这个问题提出更好的标题,我会很感激!)

2 个答案:

答案 0 :(得分:2)

我认为你的代码应该工作(如GCC或Clang),根据

  

5表达式[expr]

     

8 在某些情况下,未评估的操作数出现(5.2.8,5.3.3,5.3.7,7.1.6.2)。未评估未评估的操作数。未评估的操作数被视为完整表达式。 [注意:在未评估的操作数中,非静态类成员可能被命名为(5.1),对象或函数的命名本身并不要求提供定义(3.2)。 - 结束记录]

似乎VC ++没有实现说明所阐明的内容,因此您需要一个(伪造的)实例来解决VC ++的问题。这应该有效:

void print()
{
    std::cout << sizeof(std::declval<bar>().member_) << std::endl;
}

请注意,我删除了decltype,因为sizeof可以直接处理表达式。

答案 1 :(得分:0)

你的代码的问题可能是结构类似于类,你在类中定义了结构,但编译器在编译整个类之前不知道这个类(或结构)是否存在。