使用来自元函数的typedef声明成员函数 [英] Declaring a member function with a typedef coming from a metafunction
问题描述
考虑以下代码:
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上失败.
The declaration of foo4
fails on GCC 7.2, Clang 5.0.0 and 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;
^~~~
C语:
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
模板)且依赖于类的参数时发生.这看起来像个错误,但是这三个编译器都同意的事实令我感到怀疑.
All of them seem to think that I am trying to declare a data member with a function type. As you can see, this only happens when the type is nested (not a using
template), and is dependent on the parameter of the class. This looks like a bug, but the fact that for once all of these three compilers agree has me doubting.
这是标准行为吗?如果是这样,是否有不允许这样做的理由,是否有办法声明其成员类型是通过元程序计算的成员函数?
Is this standard behaviour? If so, is there a rationale behind disallowing this, and is there a way to declare a member function whose type is computed with a metaprogram?
推荐答案
如果函数声明通过从属类型获取其函数类型而未使用函数声明器的语法形式,则程序格式错误.
If a function declaration acquired its function type through a dependent type without using the syntactic form of a function declarator, the program is ill-formed.
这使您的最后一行绝对格式错误.这是有道理的,因为与其他依赖结构的情况一样,我们不希望短语的含义过分依赖模板参数.
This makes your last line decidedly ill-formed. Which makes sense, since, as in other cases of dependent constructs, we don't want the meaning of a phrase to depend too strongly on template arguments.
但是, [dcl.fct]/13 :
函数类型的typedef可以用来声明一个函数,但是应该 不用于定义函数.
A typedef of function type may be used to declare a function but shall not be used to define a function.
这使您的前三行格式正确-直接前两行,对于第三行,请注意
This makes your first three lines well-formed---the first two directly, and for the third one, note that
当 template-id 指代别名模板的特殊化时, 它等效于通过替换获得的关联类型 其 type-id 中 template-parameter 的 template-argument 别名模板.
When a template-id refers to the specialization of an alias template, it is equivalent to the associated type obtained by substitution of its template-arguments for the template-parameters in the type-id of the alias template.
来自 [temp.alias] .
这篇关于使用来自元函数的typedef声明成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!