在以下(最小化)代码中,我有一个引用
using
的公共 decltype(something_private)
声明:using Foo = decltype(something_private<T>)
。
在 Clang 上而不是 GCC 上,由于它是私有的,因此无法编译。
问题:
func<T>()
,有什么优雅的解决方案。 以下代码在 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
我还没有查看引用标准,但为您提供了一个解决方法。因为这有效,所以我认为 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;
}
更新:添加引用。
我认为这直接回答了你的问题,而 clang 在这里是错误的。
N4778(我发现的最新版本),10.8/p4(第 259 页)... [注意:因为访问控制适用于名称,如果访问控制适用于 typedef 名称,则仅考虑 typedef 名称本身的可访问性。不考虑 typedef 引用的实体的可访问性。