【发布时间】:2020-05-03 23:13:25
【问题描述】:
考虑以下代码:
template <class>
struct Foo_s {
using type = void();
};
template <class>
using Foo_u = void();
template <class T>
struct Bar {
Foo_u<void> foo1; // OK
typename Foo_s<void>::type foo2; // OK
Foo_u<T> foo3; // OK
typename Foo_s<T>::type foo4; // Boom.
};
template struct Bar<void>;
foo4 的声明在 GCC 7.2、Clang 5.0.0 和 MSVC 19.10.25017 上失败。
海合会:
<source>: In instantiation of 'struct Bar<void>':
18 : <source>:18:17: required from here
15 : <source>:15:29: error: field 'Bar<void>::foo4' invalidly declared function type
typename Foo_s<T>::type foo4;
^~~~
叮当声:
15 : <source>:15:29: error: data member instantiated with function type 'typename Foo_s<void>::type' (aka 'void ()')
typename Foo_s<T>::type foo4;
^
18 : <source>:18:17: note: in instantiation of template class 'Bar<void>' requested here
template struct Bar<void>;
^
MSVC:
15 : <source>(15): error C2207: 'Bar<T>::foo4': a member of a class template cannot acquire a function type
18 : <source>(18): note: see reference to class template instantiation 'Bar<void>' being compiled
他们似乎都认为我试图声明一个具有函数类型的数据成员。如您所见,这仅在类型嵌套时发生(不是using 模板),并且取决于类的参数。这看起来像一个错误,但是这三个编译器都同意的事实让我怀疑。
这是标准行为吗?如果是这样,是否有不允许这样做的理由,有没有办法声明一个其类型是用元程序计算的成员函数?
【问题讨论】:
-
是的,这是标准的。见timsong-cpp.github.io/cppwp/temp#spec-8。不知道理由或为什么
Foo_u<T>被接受。 -
可以定义这样的函数吗?例如,您如何定义
foo3? -
@geza 您只能将其用于声明,定义需要通常的语法..
-
这就是我问的原因,这个结构有什么用处?
-
@Rakete1111 所以这是一个“不,也许,不”......现在我很难过:(
标签: c++ language-lawyer c++17