我在以下代码中遇到编译错误。似乎编译器将类方法set
解释为模板 - 乍一看 - 与我的代码完全无关。
#include <cassert>
#include <limits>
using namespace std;
template <class T>
class ReduceScalar{
public:
T get() { return *r; };
void set(T t) { *r = t; };
void set(T* t) { r = t; };
private:
T* r;
};
template <class T>
class ReduceSum : public ReduceScalar<T>
{
public:
ReduceSum(T* target) { set(target); set(0); } // COMPILE ERROR
};
编译器出现以下错误:
../test/../io/scalarreducers.h:34:26: error: use of class template 'set' requires template arguments
ReduceSum(T* target) { set(target); set(0); }
但我认为这是因为它认为set
是一个模板:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__tree:685:71: note: template is declared here
template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY set;
我不明白为什么编译器会尝试为方法set
实例化该模板而不只是调用方法set
。我该如何解决这个名称混淆?
答案 0 :(得分:6)
即使你摆脱了讨厌的using namespace std
,你仍然会遇到问题。问题是成员函数set
可能不存在于所有实例中。问题中的代码使用set
作为不合格的非依赖名称。这意味着两件事:
set
。ReduceScalar<T>
的基类set
。它不可能因为该成员可能不存在于所有实例化中。最终结果:代码没有编译。解决方案是将该非依赖名称转换为依赖名称。这推迟了依赖名称的解析,直到模板实例化为止。一种方法是明确使用this
(这是一个从属名称)。
template <class T>
class ReduceSum : public ReduceScalar<T>
{
public:
ReduceSum(T* target) { this->set(target); }
};
或者,您可以使用using声明(与using指令非常不同):
template <class T>
class ReduceSum : public ReduceScalar<T>
{
public:
using ReduceScalar<T>::set;
ReduceSum(T* target) { set(target); }
};