英文:
How to Make a helper function which accepts a lambda in C++
问题
以下是您要求的代码部分的翻译:
现在我有一个函数,它对一个 uchar 数组进行一些更改(将充当查找表),以便我可以决定在该查找表上实现哪种转换。
for (size_t i = 0; i <= 255; ++i)
{
lut_transform[0].at<uchar>(i) = 255 - i; //反转函数
}
for (size_t i = 0; i <= 255; ++i)
{
lut_transform[1].at<uchar>(i) = pow((float)i * 255, (1/2.0)); //平方根函数
}
for (size_t i = 0; i <= 255; ++i)
{
lut_transform[2].at<uchar>(i) = pow((float)i, 3.0) / (255*255); //立方函数
}
所以我想改进这个,并创建一个辅助函数,该函数接收数组和要实现的函数算法作为参数。应该看起来像这样。
void transform_function_helper(std::vector<uchar>& vec_tf, lambda_arg f(int)){
for (int i = 0; i < vec_tf.size(); ++i) {
vec_tf.at<uchar>(i) = f(i);
}
}
void current_function_already_working(){
/* 代码 */
// 用辅助函数的调用替换三个 for 循环
// lut_transform 是一个 uchar 向量的向量
transform_function_helper(lut_transform[0], [](const int x) -> uchar { return 255 - x; } );
transform_function_helper(lut_transform[1], [](const int x) -> uchar { return pow((float)x * 255, (1/2.0)); } );
transform_function_helper(lut_transform[2], [](const int x) -> uchar { return pow((float)x, 3.0) / (255*255); } );
/* 代码 */
}
如果您需要进一步的帮助,请随时告诉我。
英文:
Right now I have a function which makes some changes in an array of uchar (will act as a LUT) so I can decide which transformation will be implemented on that LUT.
for (size_t i = 0; i <= 255; ++i)
{
lut_transform[0].at<uchar>(i) = 255-i; //Inverse function
}
for (size_t i = 0; i <= 255; ++i)
{
lut_transform[1].at<uchar>(i) = pow((float)i * 255,(1/2.0)); //Square Root function
}
for (size_t i = 0; i <= 255; ++i)
{
lut_transform[2].at<uchar>(i) = pow((float)i, 3.0) / (255*255); //Cubic function
}
So I want to improve this and create a helper function which receives as a parameter the array and the function algorithm to implement. So should look something like this.
void transform_function_helper (std::vector<uchar>& vec_tf, lambda_arg f(int)){
for (int i = 0; i < vec_tf.size(); ++i) {
vec_tf.at<uchar>(i) = f(i);
}
}
void current_function_already_working(){
/* code */
//replacing the 3 for for the calls to the helper function
//lut_transform is a vector of uchar vector
transform_function_helper(lut_transform[0], [](const int x) -> uchar { 255 - x; } );
transform_function_helper(lut_transform[1], [](const int x) -> uchar { pow((float)x * 255,(1/2.0)); } );
transform_function_helper(lut_transform[2], [](const int x) -> uchar { pow((float)x, 3.0) / (255*255); } );
/*code*/
}
I hope this is clear.
答案1
得分: 3
以下是代码的中文翻译部分:
你有三种选择:
- 使用纯C风格的函数指针(因为你没有使用任何捕获lambda表达式),例如:
void transform_function_helper(std::vector<uchar>& vec_tf, uchar (*f)(size_t)) {
for (size_t i = 0; i < vec_tf.size(); ++i) {
vec_tf[i] = f(i);
}
/* 或者:
size_t i = 0;
for (auto &elem : vec_tf) {
elem = f(i++);
}
*/
}
- 使用
std::function
,例如:
#include <functional>
void transform_function_helper(std::vector<uchar>& vec_tf, std::function<uchar(size_t)> f) {
for (size_t i = 0; i < vec_tf.size(); ++i) {
vec_tf[i] = f(i);
}
/* 或者:
size_t i = 0;
for (auto &elem : vec_tf) {
elem = f(i++);
}
*/
}
- 使用模板函数,例如:
template<typename Callable>
void transform_function_helper(std::vector<uchar>& vec_tf, Callable f) {
for (size_t i = 0; i < vec_tf.size(); ++i) {
vec_tf[i] = f(i);
}
/* 或者:
size_t i = 0;
for (auto &elem : vec_tf) {
elem = f(i++);
}
*/
}
无论哪种方式,然后你可以像这样调用辅助函数:
void current_function_already_working(){
/* 代码 */
// 用辅助函数替代3个循环
// lut_transform是一个uchar向量的向量
transform_function_helper(lut_transform[0], [](size_t x) -> uchar { return 255 - x; } );
transform_function_helper(lut_transform[1], [](size_t x) -> uchar { return pow((float)x * 255, (1/2.0)); } );
transform_function_helper(lut_transform[2], [](size_t x) -> uchar { return pow((float)x, 3.0) / (255*255); } );
/* 代码 */
}
英文:
You have three choices:
- use a plain C-style function pointer (since you are not using any capturing lambdas), eg:
void transform_function_helper (std::vector<uchar>& vec_tf, uchar (*f)(size_t)) {
for (size_t i = 0; i < vec_tf.size(); ++i) {
vec_tf[i] = f(i);
}
/* alternatively:
size_t i = 0;
for (auto &elem : vec_tf) {
elem = f(i++);
}
*/
}
- Use
std::function
, eg:
#include <functional>
void transform_function_helper (std::vector<uchar>& vec_tf, std::function<uchar(size_t)> f) {
for (size_t i = 0; i < vec_tf.size(); ++i) {
vec_tf[i] = f(i);
}
/* alternatively:
size_t i = 0;
for (auto &elem : vec_tf) {
elem = f(i++);
}
*/
}
- Use a template function, eg:
template<typename Callable>
void transform_function_helper (std::vector<uchar>& vec_tf, Callable f) {
for (size_t i = 0; i < vec_tf.size(); ++i) {
vec_tf[i] = f(i);
}
/* alternatively:
size_t i = 0;
for (auto &elem : vec_tf) {
elem = f(i++);
}
*/
}
Either way, you can then call the helper function like this:
void current_function_already_working(){
/* code */
//replacing the 3 for for the calls to the helper function
//lut_transform is a vector of uchar vector
transform_function_helper(lut_transform[0], [](size_t x) -> uchar { return 255 - x; } );
transform_function_helper(lut_transform[1], [](size_t x) -> uchar { return pow((float)x * 255,(1/2.0)); } );
transform_function_helper(lut_transform[2], [](size_t x) -> uchar { return pow((float)x, 3.0) / (255*255); } );
/*code*/
}
答案2
得分: 0
这就是 std::transform
的作用。如果您使用 C++20 或更新的版本,您可以使用 std::ranges::transform
:
#include <algorithm>
#include <cmath>
#include <vector>
int main(){
using uchar = unsigned char;
std::vector<uchar> data{3, 5, 8};
std::ranges::transform(data, data.begin(),
[](const uchar x) {
return static_cast<uchar>(255 - x);
});
std::ranges::transform(data, data.begin(),
[](const uchar x) {
return static_cast<uchar>(std::pow(x * 255, 0.5));
});
std::ranges::transform(data, data.begin(),
[](const uchar x) {
return static_cast<uchar>(std::pow(x, 3.0) / (255 * 255));
});
}
请注意,如果使用整数参数,std::pow
会自动转换为 double
类型。此外,请注意,我已将 lambda 表达式的参数类型更改为 uchar
,这是向量的实际类型。在 lambda 表达式中的显式 static_cast
更好,因为它可以抑制隐式转换警告。
在 C++20 之前(C++11)的代码如下:
#include <algorithm>
#include <cmath>
#include <vector>
int main(){
using uchar = unsigned char;
std::vector<uchar> data{3, 5, 8};
std::transform(data.cbegin(), data.cend(), data.begin(),
[](const uchar x) {
return static_cast<uchar>(255 - x);
});
std.transform(data.cbegin(), data.cend(), data.begin(),
[](const uchar x) {
return static_cast<uchar>(std::pow(x * 255, 0.5));
});
std.transform(data.cbegin(), data.cend(), data.begin(),
[](const uchar x) {
return static_cast<uchar>(std::pow(x, 3.0) / (255 * 255));
});
}
英文:
This is what std::transform
does. If you use C++20 or newer, you can use std::ranges::transform
:
#include <algorithm>
#include <cmath>
#include <vector>
int main(){
using uchar = unsigned char;
std::vector<uchar> data{3, 5, 8};
std::ranges::transform(data, data.begin(),
[](const uchar x) {
return static_cast<uchar>(255 - x);
});
std::ranges::transform(data, data.begin(),
[](const uchar x) {
return static_cast<uchar>(std::pow(x * 255, 0.5));
});
std::ranges::transform(data, data.begin(),
[](const uchar x) {
return static_cast<uchar>(std::pow(x, 3.0) / (255 * 255));
});
}
Note that std::pow
automatically casts to double
if use use integer arguments. Also note that I replaced the lambdas parameter type to uchar
which is the vectors actual type. The explicit static_cast
in the lambdas is better then explicit return type notation, because it suppresses implicit conversion warnings.
The pre C++20 (C++11) code would be:
#include <algorithm>
#include <cmath>
#include <vector>
int main(){
using uchar = unsigned char;
std::vector<uchar> data{3, 5, 8};
std::transform(data.cbegin(), data.cend(), data.begin(),
[](const uchar x) {
return static_cast<uchar>(255 - x);
});
std::transform(data.cbegin(), data.cend(), data.begin(),
[](const uchar x) {
return static_cast<uchar>(std::pow(x * 255, 0.5));
});
std::transform(data.cbegin(), data.cend(), data.begin(),
[](const uchar x) {
return static_cast<uchar>(std::pow(x, 3.0) / (255 * 255));
});
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论