在以下(最小化)代码中,我有一个公共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
答案 0 :(得分:9)
我没有考虑引用标准,但是为您提供了一种解决方法。因为这样做有效,所以让我认为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;
}
更新:添加了引文。
我认为这直接回答了您的问题,而这里的叮当声是错误的。
N4778(我找到的最新版本),10.8 / p4(第259页)... [注意:由于访问控制适用于名称,因此,如果将访问控制应用于typedef名称,则只有typedef名称本身的可访问性是考虑过的。不考虑由typedef引用的实体的可访问性。