公共"使用"= decltype(<private>)

Una*_*dra 12 c++ templates decltype language-lawyer c++11

在下面(最小化)代码中,我有一个公开using声明,指的是decltype(something_private):using Foo = decltype(something_private<T>).

在Clang但不是GCC,因为它是私有的,所以不会编译.

问题:

  1. 如果我不想func<T>()公开,什么是优雅的解决方案.
  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;
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/zD4Hk5

Chr*_*nis 9

我没有看过引用的标准,但有一个解决方法给你.因为这有效,它让我觉得clang只是有一个bug.当函数直接在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;
}
Run Code Online (Sandbox Code Playgroud)

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

更新:添加引文.

我认为这直接回答了你的问题,而且这里的铿锵有误.

N4778(我发现的最新版本),10.8/p4(第259页)... [注意:由于访问控制适用于名称,如果将访问控制应用于typedef名称,则仅考虑typedef名称本身的可访问性.不考虑typedef引用的实体的可访问性.