【发布时间】:2015-11-26 18:03:24
【问题描述】:
考虑以下代码:
template<int X, int Y>
struct S
{
typedef int func(int,float) const;
};
template<int X>
struct D : public S<X,6>
{
typename S<X,6>::func func;
};
template<int X>
int D<X>::func(int,float) const
{
return 1;
}
//----------------
struct W : public S<7,8>
{
S<7,8>::func func;
};
int W::func(int,float) const
{
return 2;
}
#include <iostream>
int main()
{
W w;
std::cout << w.func(1,4.3) << "\n";
D<3> d;
std::cout << d.func(1,4.3) << "\n";
}
如果我注释掉声明类D 和D::func() 的代码以及main() 中的相应行,则代码编译正常,并且我在输出中看到2,正如预期的那样。
但是当我制作派生类模板时(在函数声明之前添加typename,因为S<X.6>是一个依赖范围),我得到以下错误:
test.cpp:13:27: error: no ‘int D<X>::func(int, float) const’ member function declared in class ‘D<X>’
int D<X>::func(int,float) const
^
test.cpp: In instantiation of ‘struct D<3>’:
test.cpp:32:10: required from here
test.cpp:10:27: error: field ‘D<3>::func’ invalidly declared function type
typename S<X,6>::func func;
^
- 为什么我不能在模板派生类中声明
func,而在非模板类中却可以? - 究竟什么是“无效声明的函数类型”?这里什么无效?
【问题讨论】:
-
我感觉这在规范中的 [dcl.fct]/10 在技术上是有效的,但是声明一个具有依赖 typedef 的函数就像是极端情况的极端情况:我是不确定是否有任何编译器会像你期望的那样处理它。
-
我会说
S<X,6>可能是后者,所以D<X>::func的定义可能会失效。 -
@Jarod42 看起来我们需要
function_typename以及typename:p -
请注意,在
D中使用typename S<7,6>::func func;有效(Demo)。 -
@Jarod42 这并不奇怪,因为它与
W中的大部分内容相同。在这种情况下,您甚至不需要typename,因为S<7,6>不是依赖范围。
标签: c++ templates methods types