在 transform() 中调用成员函数
Calling member function in transform()
所以我一直在尝试使用转换函数从 2 个现有向量创建一个向量。我在没有 类 的情况下成功地做到了,但现在我想使用 类 并且出现错误。下面的代码只是我项目的一小部分相关部分,所以它可能看起来很愚蠢,但最终整个事情实际上是有意义的。
这是我的头文件的一部分:
#include <vector>
#include <algorithm>
class Example
{
public:
double multiply(double x, double y);
void generate_amplitude(std::vector<double>& ampVec);
};
还有我的 .cpp 文件的一些内容:
#include "example.h"
double Example::multiply(double x, double y)
{
return x*y;
}
void Example::generate_amplitude(std::vector<double>& ampVec)
{
double const a = 3.14;
int const lenVectors = 10;
std::vector<double> timeVec = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9}
std::vector<double> ampVec(lenVectors);
std::vector<double> aVec(lenVectors, a);
// Fill ampVec with timeVec[i]*aVec[i] for i in range[0:lenVectors[
transform(timeVec.begin(), timeVec.end(), aVec.begin(), ampVec.begin(), multipy);
}
所以当我尝试编译时,我得到:
error: must use '.*' or '->*' to call pointer-to-member function in '__binary_op (...)', e.g. '(... ->* __binary_op) (...)'
我确实搜索并阅读了数小时有关指向成员函数的指针,尝试了几种不同的方法,例如:
double (Example::*pmf)(double, double);
pmf = &Example::multiply;
transform(timeVec.begin(), timeVec.end(), aVec.begin(), ampVec.begin(), this->*pmf);
但我对此还是个新手,找不到让它发挥作用的方法。这个特定的例子返回了那种消息:
error: no matching function for call to 'transform(std::vector<double>::iterator, std::vector<double>::iterator, std::vector<double>::iterator, std::vector<double>::iterator, double (Example::)(double, double))'
note: candidate: 'template<class _IIter, class _OIter, class _UnaryOperation> _OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation)'
note: candidate expects 4 arguments, 5 provided
note: template argument deduction/substitution failed
note: candidate: 'template<class _IIter1, class _IIter2, class _OIter, class _BinaryOperation> _OIter std::transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation)'
note: member function type 'double (Example::)(double, double)' is not a valid template argument
不胜感激!
解决此问题的最简单方法是使用 lambda:
transform(
timeVec.begin(), timeVec.end(),
aVec.begin(),
ampVec.begin(),
[this](double a, double b) { return multiply(a, b); }
);
你不能在这里使用指向成员函数的指针,因为你需要 this
指针来调用指向成员函数的指针,而 std::transform()
没有提供此信息的机制。用 lambda 捕获它通过使 this
成为函子状态的一部分来解决这个问题。
您可以通过编写自定义函子在 C++03 中做类似的事情:
class ExampleMultiply {
public:
explicit ExampleMultiply(Example &p) : example(p) {}
double operator()(double a, double b) const {
return example.multiply(a, b);
}
private:
Example &example;
};
然后用这个仿函数调用 std::transform()
:
transform(
timeVec.begin(), timeVec.end(),
aVec.begin(),
ampVec.begin(),
ExampleMultiply(*this)
);
在幕后,这基本上就是编译器为实现 lambda 表达式而生成的内容。
所以我一直在尝试使用转换函数从 2 个现有向量创建一个向量。我在没有 类 的情况下成功地做到了,但现在我想使用 类 并且出现错误。下面的代码只是我项目的一小部分相关部分,所以它可能看起来很愚蠢,但最终整个事情实际上是有意义的。
这是我的头文件的一部分:
#include <vector>
#include <algorithm>
class Example
{
public:
double multiply(double x, double y);
void generate_amplitude(std::vector<double>& ampVec);
};
还有我的 .cpp 文件的一些内容:
#include "example.h"
double Example::multiply(double x, double y)
{
return x*y;
}
void Example::generate_amplitude(std::vector<double>& ampVec)
{
double const a = 3.14;
int const lenVectors = 10;
std::vector<double> timeVec = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9}
std::vector<double> ampVec(lenVectors);
std::vector<double> aVec(lenVectors, a);
// Fill ampVec with timeVec[i]*aVec[i] for i in range[0:lenVectors[
transform(timeVec.begin(), timeVec.end(), aVec.begin(), ampVec.begin(), multipy);
}
所以当我尝试编译时,我得到:
error: must use '.*' or '->*' to call pointer-to-member function in '__binary_op (...)', e.g. '(... ->* __binary_op) (...)'
我确实搜索并阅读了数小时有关指向成员函数的指针,尝试了几种不同的方法,例如:
double (Example::*pmf)(double, double);
pmf = &Example::multiply;
transform(timeVec.begin(), timeVec.end(), aVec.begin(), ampVec.begin(), this->*pmf);
但我对此还是个新手,找不到让它发挥作用的方法。这个特定的例子返回了那种消息:
error: no matching function for call to 'transform(std::vector<double>::iterator, std::vector<double>::iterator, std::vector<double>::iterator, std::vector<double>::iterator, double (Example::)(double, double))'
note: candidate: 'template<class _IIter, class _OIter, class _UnaryOperation> _OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation)'
note: candidate expects 4 arguments, 5 provided
note: template argument deduction/substitution failed
note: candidate: 'template<class _IIter1, class _IIter2, class _OIter, class _BinaryOperation> _OIter std::transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation)'
note: member function type 'double (Example::)(double, double)' is not a valid template argument
不胜感激!
解决此问题的最简单方法是使用 lambda:
transform(
timeVec.begin(), timeVec.end(),
aVec.begin(),
ampVec.begin(),
[this](double a, double b) { return multiply(a, b); }
);
你不能在这里使用指向成员函数的指针,因为你需要 this
指针来调用指向成员函数的指针,而 std::transform()
没有提供此信息的机制。用 lambda 捕获它通过使 this
成为函子状态的一部分来解决这个问题。
您可以通过编写自定义函子在 C++03 中做类似的事情:
class ExampleMultiply {
public:
explicit ExampleMultiply(Example &p) : example(p) {}
double operator()(double a, double b) const {
return example.multiply(a, b);
}
private:
Example &example;
};
然后用这个仿函数调用 std::transform()
:
transform(
timeVec.begin(), timeVec.end(),
aVec.begin(),
ampVec.begin(),
ExampleMultiply(*this)
);
在幕后,这基本上就是编译器为实现 lambda 表达式而生成的内容。