【问题标题】:C++ Invalid use of non-static data memberC++ 无效使用非静态数据成员
【发布时间】:2014-11-24 09:46:31
【问题描述】:

我想将函数作为参数传递给模板化函数,而不需要任何间接。为了实现这一点,我创建了两个嵌套结构,每个都定义了我希望传递给模板化函数的函数。每个结构都从外部class B访问数据成员:

namespace A{
    class B{
        public:
            B();

            template <typename T>
            void templatedFunction(T t){
                //I pass one of the struct objects in to here, to invoke the desired function 
                t();
            }

        private:
            struct X{
                void operator(){
                    do();
                }

                void do(){
                    //Accesses the data members of class B
                    e->doSomething();
                }
            };

            struct Y{
                void operator(){
                    do();
                }

                void do(){
                    //Accesses the data members of class B
                    d.doSomething();
                }
            };

            C* c;
            D d;
            E* e;
    };
}

我得到的编译器错误几乎都是格式:

错误:非静态数据成员 B::d 的使用无效

用于访问类数据成员的结构中的行以及在B 中声明数据成员的行。

【问题讨论】:

  • 你不应该像这样调用templatedFunction中的函子吗:t()
  • 谢谢 - 必须从头开始输入代码。
  • 回滚了最新的编辑,因为它使已发布的回答无效。 不要那样做。请不要在发布答案后更改代码或问题。

标签: c++ class oop struct


【解决方案1】:

C++ 中的嵌套类不会(自动)访问包含类的实例。它只是一个类定义,就像其他任何东西一样。您需要一个B 实例来访问B 的非静态数据成员。


您可以将嵌套类Y 重构为

struct Y
{
    void operator()( B& b ){
        do( b );
    }

    void do( B& b ){
        //Accesses the data members of class B
        b.d.doSomething();
    }
};

并相应地修复您的函数模板和调用以及类X

请注意,您为operator() 提供的代码,没有参数列表,不会编译,但我没有反对,因为您被另一个编译错误阻止(即,可能是您正在显示的真实代码)。

【讨论】:

  • 除了传递B的实例真的没有其他解决方案吗?
  • 我明白为什么我会在访问结构中的成员时遇到编译器错误。我不明白为什么这会导致 B 中的变量声明行出现编译器错误?
  • @user997112:不管主题如何,任何关于“不可能”的笼统陈述迟早都会被反驳,所以我不会这么说。但我现在想不出任何实用的其他解决方案。然而,当考虑更多问题的上下文时可能会很明显,但不幸的是没有指定上下文。
  • 我的首要问题是我希望将两个函数之一作为参数传递给另一个函数。但是,我想避免函数指针的指针间接开销。
  • @user997112:成员函数可以并且可能会被内联,从而避免函数指针“开销”。但是,在任何情况下,当明显的效率考虑决定了设计时,MEASURE 可能是一个好主意。把一些数字放在桌子上。
【解决方案2】:

如果你有一个结构(或类)嵌套在另一个类中,它不会以任何方式进行特殊处理。它的工作方式与结构是在封闭类之外定义的完全相同。唯一不同的是嵌套类名的范围。所以,如果你有

class A { class B{}; };

class B{}; class A {};

唯一的区别是在A之外的类在第一种情况下你需要将B命名为A::B,在第二种情况下只需B。没有其他区别,特别是 B 类没有对 A 类成员的任何特殊访问权限。

【讨论】:

  • 那么我如何从 B 中访问 A 的成员(第一种情况)?
  • -1 "特别是 B 类没有获得对 A 类成员的任何特殊访问权限"
  • 和第二种情况一样。你需要例如将对A 的引用传递给B 的成员函数。
  • @WojtekSurowka:至少 Visual c++ 和 g++ 不同意引用的声明。我相信你可以找到相关的标准。请注意,关于规则有一些反复,但我不确定这是否发生在第一个 iso 标准(1998 年)之后。
  • @Cheersandhth.-Alf 介意举个例子吗? 9.7 中的 C++11 文本仅讨论范围,没有其他内容(“一个类可以在另一个类中声明。在另一个类中声明的类称为嵌套类。嵌套类的名称对其封闭类是本地的. 嵌套类在其封闭类的范围内。")
猜你喜欢
  • 2016-01-12
  • 2023-03-12
  • 2013-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-22
  • 1970-01-01
  • 2017-09-12
相关资源
最近更新 更多