公开“使用”= decltype(<private>)

问题描述 投票:0回答:1

在以下(最小化)代码中,我有一个引用

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;
}

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个回答
9
投票

我还没有查看引用标准,但为您提供了一个解决方法。因为这有效,所以我认为 clang 只是有一个错误。当函数直接位于 A 中时,它将类型别名视为在调用者的上下文中,但将函数移至结构中可以解决此问题。 Meh.我最近做了很多 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(第 259 页)... [注意:因为访问控制适用于名称,如果访问控制适用于 typedef 名称,则仅考虑 typedef 名称本身的可访问性。不考虑 typedef 引用的实体的可访问性。

© www.soinside.com 2019 - 2024. All rights reserved.