【问题标题】:Public "using" = decltype(<private>)公共“使用”= decltype(<private>)
【发布时间】:2019-03-23 21:35:24
【问题描述】:

在以下(最小化)代码中,我有一个公开的using 声明,它指的是decltype(something_private)using Foo = decltype(something_private&lt;T&gt;)

在 Clang 而不是 GCC 上,由于它是私有的,因此无法编译。

问题:

  1. 如果我不想公开func&lt;T&gt;(),有什么优雅的解决方案。
  2. 在 C++ 标准 (C++11) 中,备份 Clang 在哪里是正确的?

以下代码在 Clang (3.9 - 7.0) 上失败并出现以下错误代码,但在 GCC (4.8.4 - 8.2) 上构建:

class A {
private:
    template <class T>
    static auto func() -> T; // The actual return type is much
       // more complicated, so `using Foo = T` would not work.

public:
    template <class T>
    using Foo = decltype(func<T>());
};

int main(int, char**) {
    A::Foo<int> y;
    return y;
}

Clang 7.0 输出:

<source>:10:24: error: 'func' is a private member of 'A'
  using Foo = decltype(func<T>());
                       ^~~~~~~

<source>:14:7: note: in instantiation of template type alias 'Foo' requested here
   A::Foo<int> y;
          ^

<source>:6:15: note: declared private here
  static auto func() -> T;
              ^

1 error generated.
Compiler returned: 1

https://godbolt.org/z/zD4Hk5

【问题讨论】:

标签: c++ c++11 templates language-lawyer decltype


【解决方案1】:

我没有查看引用标准,但有一个解决方法。因为这行得通,它让我觉得 clang 只是有一个错误。当函数直接在 A 中时,它会将类型别名视为在调用者的上下文中,但是将函数移动到结构中可以解决这个问题。嗯。我最近做了很多 g++ / clang 移植,虽然我没有特别遇到这个,但它闻到了我遇到的一些东西。

class A {
private:
  struct X {
    template <class T>
    static auto func() -> T;
  };

public:
  template <class T>
  using Foo = decltype(X::func<T>());
};

void bar() {
   A::Foo<int> y;
}

https://godbolt.org/z/ozIS-r

更新:添加引用。

我认为这直接回答了您的问题,而这里的 clang 是错误的。

N4778(我找到的最新),10.8/p4(pg 259)... [注意:因为访问控制适用于名称,如果访问控制适用于 typedef 名称,则只有 typedef 名称本身的可访问性是经过考虑的。不考虑 typedef 引用的实体的可访问性。

【讨论】:

  • 感谢您的回答!在要求对标准进行澄清时,我过去一直偏向于 GCC 过于宽松,而 Clang 通常严格遵守标准。这是第一次,我不确定 Clang 是否过于严格。这就是为什么我仍然在这方面寻求答案。
  • @Unapiedra,我也有这些担忧,但 struct X 也是 A 私有的,A::X::func() 仍然是 bar() 私有的。我认为它应该始终有效或无效。无论如何,我找到了一个令我满意的引文,并更新了我的答案以包含它。
猜你喜欢
  • 1970-01-01
  • 2017-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-10
  • 2017-01-15
相关资源
最近更新 更多