【问题标题】:using declaration cannot refer to class memberusing 声明不能引用类成员
【发布时间】:2019-10-25 07:21:06
【问题描述】:

基本上,命名空间np中定义了一个类Foo

//Foo.h
namespace np {

    class Foo {
        public:
          static void static_member();
         ...
        }
...
}

我想在其他来源中引用静态成员,比如src.cc

//src.cc
#include "Foo.h"

using np::Foo::static_member;
...
static_member()
...

启动编译器后报错:

 error: using declaration cannot refer to class member

但是,当我将线路更改为 np::Foo::static_member() 时,它起作用了。那么,省略无休止的作用域前缀的正确方法是什么?

【问题讨论】:

  • 没有办法,除非Foo 是命名空间,而不是class(或struct)类型。该函数的调用也需要在另一个函数中。 np::Foo::static_member() 可以在 np::Foo 的成员函数中不合格地调用

标签: c++ namespaces static-methods


【解决方案1】:

那么,省略无休止的作用域前缀的正确方法是什么?

没有办法。在类范围之外,using 声明可以引用类中的嵌套类型,但不能引用数据成员,请参阅here

你能得到的最短的是

using namespace np;
Foo::static_member();

或者使用指向成员的指针,它更短但也更容易混淆:

auto static_member = &np::Foo::static_member;
static_member();

【讨论】:

  • 嗨,我试过decltype(np::Foo::static_member)* static_member(我认为和你的第二个解决方法一样),编译成功但是程序在static_member()的调用下崩溃了;我正在使用 Android NDK,回溯并没有告诉任何有关此崩溃的信息:(
  • 如果您使用decltype 版本,您必须确保指向成员的指针已初始化。您看到的崩溃可能是您尝试通过未指向内存中某个有效位置的指针调用函数。
【解决方案2】:

我不确定您的用例是什么,但我会选择两种方式之一(或者可能是三种?):

1) 如果它适用,请尝试将此静态方法移动到命名空间中 - 因为它是静态的,这可能对您有用(如果您需要将此东西作为某种模板类传递,那么这种方法将不起作用) . 看看其他人对此的看法:

Namespace + functions versus static methods on a class https://softwareengineering.stackexchange.com/questions/134540/are-utility-classes-with-nothing-but-static-members-an-anti-pattern-in-c

namespace np
{
  void static_non_member();
} // namespace np

// .. in .cpp, should be fine to do this
{
  using namespace np;
  static_non_member();
}

2) 使用声明可以很好地与类一起使用,因此您至少可以减少必须编写的代码量:

// assume same hpp
// cpp
#include "Foo.h"

using Foo = np::Foo;

Foo::static_member();

3) 奖励回合:存储指向该函数的指针

#include <type_traits>

using FunctionPtrT = std::add_pointer<void()>::type;
FunctionPtrT static_ptr = &Foo::static_member;

// Foo::static_member();
static_ptr(); // name this whatever you wish

【讨论】:

    【解决方案3】:

    您不必添加using np::Foo::static_member;

    如果包含 Foo.h 并且函数是 public,则可以使用任何 static 函数

    例如:

    // Foo.h
    namespace np
    {
      Class Foo
      {
        public:
          static void PrintHello();
      }
    }
    
    // Foo.cpp
    #include "Foo.h"
    #include <iostream>
    
    void np::Foo::PrintHello()
    {
      printf("Hello World!\n");
    }
    
    // main.cpp
    #include "Foo.h"
    int Main()
    {
      np::Foo::PrintHello();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-27
      • 2012-06-22
      • 1970-01-01
      • 2023-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多