1

目标

我的目标是StaticLibrary::func()使用点语法从 Environment 的属性(未命名的类)中调用。

例如:

env.bar.func();

我已经能够实现static_cast<StaticLibrary>(env.bar).func();,很接近了,但是语法还是太繁琐了。

问题

可以推断出静态转换,还是可以重载某些运算符以获得所需的语法?

注意:我有一个不能StaticLibrary直接作为Environment类的公共成员(对象、引用或指针)的约束。

错误

我目前收到错误(我理解,但为了完整起见粘贴在这里):

unnamedDotSyntax.cpp: In function ‘int main()’:
unnamedDotSyntax.cpp:48:13: error: ‘class Environment::<anonymous>’ has no member named ‘func’
     env.bar.func();
             ^

代码

下面的示例是我能提供的最精炼的代码版本。

#include <iostream>

class StaticLibrary {
  public:
    int func (void) {
        std::cout << "called " << __FUNCTION__ << std::endl;
    }
};

class Environment {
  public:
    Environment (void) {
        bar.sl = &sl;
    }

    inline
    int foo (void) {
        std::cout << "called " << __FUNCTION__ << std::endl;
    }

    class {
        friend Environment;
      public:
        operator StaticLibrary & (void) {
            return *sl;
        }
      private:
        StaticLibrary * sl;
    } bar;

  private:
    StaticLibrary sl;
};

int main (void) {
    Environment env;
    env.foo();

    // Works
    StaticLibrary sl = env.bar;
    sl.func();

    // Works, but the syntax is too cumbersome. Can the static cast be inferred somehow?
    static_cast<StaticLibrary>(env.bar).func();

    // unnamedDotSyntax.cpp:48:13: error: ‘class Environment::<anonymous>’ has no member named ‘func’
    //      env.bar.func();
    env.bar.func();
}

注意:这必须与 GCC 兼容,而不是 Microsoft VC++

4

1 回答 1

0

对于嵌套类,无法复制 的接口StaticLibrary,因为成员访问运算符 ( .) 不应用任何转换。func()所以要调用bar你需要有一个成员函数func()。如果转换为具有成员函数的东西是bar不够的(因为这可能是模棱两可的)。barfunc()

也就是说,您可以通过委托成员函数来包装StaticLibraryinside的接口,或者您可以创建一个类型的公共数据成员(这是您的约束所禁止的)。barint func() { return sl.func(); }barStaticLibrary

在这里,我给嵌套类起了一个名字,因为它使错误更具可读性,并且我存储引用而不是指针,因为我喜欢值语义。

#include <iostream>

class StaticLibrary {
public:
  int func() {
    std::cout << "called " << __FUNCTION__ << std::endl;
    return 0;
  }
};

class Environment {
private:
  StaticLibrary sl;
public:

  class Bar {
    friend Environment;
    StaticLibrary& sl;
  public:
    explicit Bar(StaticLibrary& _sl) : sl(_sl) {};
    operator StaticLibrary& () { return sl; }
    int func() { return sl.func(); }
  } bar;

  Environment() : sl{}, bar{sl} {};

  int foo() {
    std::cout << "called " << __FUNCTION__ << std::endl;
    return 0;
  }
};

int main (void) {
    Environment env;
    env.foo();

    // Works
    StaticLibrary sl = env.bar;
    sl.func();

    // Works, but the syntax is too cumbersome. Can the static cast be inferred somehow?
    static_cast<StaticLibrary>(env.bar).func();

    // unnamedDotSyntax.cpp:48:13: error: ‘class Environment::<anonymous>’ has no member named ‘func’
    //      env.bar.func();
    env.bar.func();
}
于 2017-08-09T21:25:10.007 回答