c++ - C ++:对仿函数的重载调用运算符的未定义引用
问题描述
template <typename T>
class Predicate {
public:
bool operator()(const T& x) const;
};
template <typename T>
class LessThan : public Predicate<T> {
public:
explicit LessThan(const T& v) : val(v) {}
bool operator()(const T& x) const { return x < val; }
private:
const T val;
};
template <typename C, typename T>
class Producer {
public:
T operator()(const C& c) const;
};
template <typename C, typename V>
class HowMuch : public Producer<C, int> {
public:
explicit HowMuch(Predicate<V> p) : predicate{p} {}
int operator()(const C& c) const {
int count = 0;
for (const auto& x : c)
if (predicate(x)) ++count;
return count;
}
private:
Predicate<V> predicate;
};
int main() {
const LessThan<int> lf(5);
const HowMuch<list<int>, int> hm(lf);
list<int> li {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
cout << "How much numbers less than 5 is in {1, 2, 3, 4, 5, 6, 7, 8, 9, "
"10}? Answer: "
<< hm(li)
<< endl;
}
编译上述代码时,g++ 将其打印到控制台:
/tmp/ccblK6El.o:在函数中
HowMuch<std::__cxx11::list<int,
std::allocator<int> >, int>::operator()(std::__cxx11::list<int,
std::allocator<int> > const&) const
:templates.cpp:(.text._ZNK7HowMuchINSt7__cxx114listIiSaIiEEEiEclERKS3_[_ZNK7HowMuchINSt7__cxx114listIiSaIiEEEiEclERKS3_]+0x84):未定义对Predicate<int>::operator()(int const&) const
collect2的引用:错误:ld返回1退出状态终端进程以退出代码终止:1
我不太明白Prediate<V>
里面的定义有什么问题HowMuch
,因为对我来说(C++ 的新手)它看起来真的是 LGTM。据我了解,编译器创建了Predicate<int>
一个单独类型的定义,并且日志准确地说明了这一点,但由于某种原因,它找不到重载调用运算符的类型化定义。可能是类型扣除的问题?容器模板类型本身的模板必须以某种方式显式定义?
编辑:
virtual
修饰符被添加到Predicate
' 和Producer
' 函数运算符重载中,但问题似乎仍然存在。但是,错误“描述”(如果可以称为有用的描述)有所更改(但仍然指向相同的问题):
/tmp/ccn1Swqa.o: 在函数 HowMuch >, int>::operator()(std::__cxx11::list > const&) const: templates.cpp:(.text._ZNK7HowMuchINSt7__cxx114listIiSaIiEEEiEclERKS3_[_ZNK7HowMuchINSt7__cxx114listIiSaIiEEEiEclERKS3_]+0x to Predicate::operator()(int const&) const /tmp/ccn1Swqa.o:(.rodata._ZTV8ProducerINSt7__cxx114listIiSaIiEEEiE[_ZTV8ProducerINSt7__cxx114listIiSaIiEEEiE]+0x10): 未定义对 Producer >, int>::operator()(std::__cxx11: :list > const&) const /tmp/ccn1Swqa.o:(.rodata._ZTV9PredicateIiE[_ZTV9PredicateIiE]+0x10): undefined reference to Predicate::operator()(int const&) const collect2: error: ld returned 1 exit status 终端进程以退出代码终止:1
解决方案
您需要为类的所有功能提供定义。这意味着即使您只派生类Predicate
,Producer
您仍然必须operator()
在这些类中实现。
如果您不想这样做(即只有函数声明但没有定义),请考虑通过声明方法来使这两个类抽象为pure virtual。然后,您不能直接从这些类实例化对象,而只能从实现该方法的派生类实例化。这也意味着你只能传入你的构造函数。operator()
operator()
Predicate<V>*
HowMuch
推荐阅读
- javascript - 如何禁用滑动滑块中的拖动
- javascript - 在 JavaScript 中,您可以从 ForEach 循环内部将数组推送到外部变量吗?它不工作
- python - 2个相同代码之间的区别
- python - Python - while 循环的问题
- firebase - 如何从firebase颤振中提取带有流的嵌套引用
- security - 身份验证跟随是如何设计的?
- reactjs - 获得不变违规:ListView 在本机反应,但我没有使用任何列表视图
- json - 如何使用 jq 获取第一个数据?
- android - Android后退导航导致基于意图的活动崩溃
- build - 线程“主”java.lang.NoSuchMethodError 中的 Oozie 异常:org.apache.log4j.config.PropertySetter.activate()V