prog.cpp:9:13: error: ‘result_type’ does not name a type
prog.cpp:9:13: note: (perhaps ‘typename std::unary_function<_Arg, _Result>::result_type’ was intended)
为什么我不能直接使用result_type?
#include <functional>
using namespace std;
template <typename ARGUEMENT, typename RESULT>
class FunctorBase : public std::unary_function<ARGUEMENT, RESULT>
{
public:
virtual result_type operator () (argument_type) = 0;
FunctorBase() {}
virtual ~FunctorBase() {}
};
int main()
{
FunctorBase<int&, void>();
}
答案 0 :(得分:3)
因为result_type
和argument_type
取决于模板参数。使用:
virtual typename std::unary_function<ARGUEMENT, RESULT>::result_type
operator () (typename std::unary_function<ARGUEMENT, RESULT>::argument_type) = 0;
或者,如果您需要更多地方,请添加
using typename std::unary_function<ARGUEMENT, RESULT>::result_type;
using typename std::unary_function<ARGUEMENT, RESULT>::argument_type;
在你班级的开头。
答案 1 :(得分:3)
因为它是非限定名称。
当您在类模板中使用非限定名称时,您必须告诉编译器它不应该在两阶段名称查找的第一阶段中立即搜索全局名称,而是等到实例化(因为名称可以来自基类,就像这里的情况一样。)
在这种情况下,您可以执行此操作(并使result_type
成为依赖,限定名称):
typedef typename std::unary_function<ARGUEMENT, RESULT>::result_type result_type;
请注意,这同样适用于argument_type
。
typedef typename std::unary_function<ARGUEMENT, RESULT>::argument_type argument_type;
使用这两个typedef
,原始成员函数声明现在将编译:
virtual result_type operator () (argument_type) = 0;
答案 2 :(得分:0)
您可以在班级中重新定义它:
typedef typename std::unary_function<ARGUEMENT, RESULT>::result_type my_result_type;
(你甚至可以将它重命名为完全相同的东西) 即使您从中继承的是私有的,这也可以工作。
这compiles:
template <typename blah>
class MyTemplateBaseClass
{
public:
typedef blah my_blah_typedef;
};
template <typename arg>
class DerivedFromTemplated : private MyTemplateBaseClass<arg>
{
public:
//Either giving the full name:
typename MyTemplateBaseClass<arg>::my_blah_typedef GetBlahType()
{
return typename MyTemplateBaseClass<arg>::my_blah_typedef();
}
//Or typedef-ing it locally:
typedef typename MyTemplateBaseClass<arg>::my_blah_typedef my_blah_typedef;
my_blah_typedef GetBlahType2()
{
return my_blah_typedef();
}
};
int main()
{
DerivedFromTemplated<int> test;
}