Hy @ all, 我们必须实现以下功能调用:
std::mt19937 engine;
color_table lut = create_random_color_map(engine);
发动机必须是可更换的。我们试图用这种方式实现它:
的 *。HPP
#include <tuple>
#include <random>
typedef std::tuple<unsigned char,unsigned char,unsigned char> rgb_tuple;
class color_table{
public:
[...]
void generate(rgb_tuple predicate(const unsigned char& index));
};
template <class RANDOM>
static rgb_tuple random_color(RANDOM engine){
std::uniform_int_distribution<int> dist1 (0,255);
unsigned char red = (unsigned char) dist1();
unsigned char green = (unsigned char) dist1(engine);
unsigned char blue = (unsigned char) dist1(engine);
return std::make_tuple(red, green, blue);
}
template <class RANDOM>
static color_table create_random_color_map(RANDOM engine){
color_table lut;
lut.generate([&](const unsigned char& i)->rgb_tuple {
return random_color<decltype(engine)>(engine);
} );
return lut;
}
*的的.cpp
...
void color_table::generate(rgb_tuple predicate(const unsigned char& index)){
for(int i = 0; i < 256; ++i){
std::tie(red_table[i], green_table[i], blue_table[i]) = predicate(i);
}
}
当我们尝试编译时,会发生以下错误:
错误C2664:'color_table :: generate':转换参数1 从 'create_random_color_map ::' 'rgb_tuple(__ cdecl *)(const unsigned char&amp;)'不可能1&gt;
没有用户定义的convertionoperator,可以执行 转换或运算符不能被调用。 ... 功能模板“color_table create_random_color_map(RANDOM)“。与[
RANDOM = std :: mt19937]
我们对这种失败完全无能为力,谷歌在这种情况下不是我们的朋友! :/
我们感谢任何帮助!
此致 希密尔
答案 0 :(得分:3)
第一个(主要)问题:
您的函数generate()
接受函数指针作为其参数,并且您正在尝试传递捕获lambda。不幸的是,捕获lambda不能隐式转换为函数指针。根据C ++ 11标准的5.1.2 / 6段:
没有 lambda-capture 的 lambda-expression 的闭包类型具有公共非虚拟非显式const 转换函数指向函数,该函数具有与闭包类型相同的参数和返回类型 函数调用运算符。此转换函数返回的值应为函数的地址 当被调用时,它与调用闭包类型的函数调用操作符具有相同的效果。
您可以更改设计并让generate()
成为函数模板,接受可调用对象作为其参数:
class color_table{
public:
template<typename P>
void generate(P predicate);
};
或者,您可以使用std::function
包装器来实现灵活性,而不会重复使用模板(但需要一些运行时开销):
#include <functional> // <== NEEDED FOR std::function
class color_table{
public:
void generate(std::function<rgb_tuple(const unsigned char&)> predicate);
};
这是一个live example,显示使用上述解决方案编译的代码。
第二(次要)问题:
您不应明确指定random_color()
的模板参数。而是让编译器完成其工作并执行类型推导:
lut.generate([&](const unsigned char& i)->rgb_tuple {
return random_color(engine);
// ^^^^^^^^^^^^^^^^^^^^^
});
答案 1 :(得分:0)
我认为问题在于你:
void generate(rgb_tuple predicate(const unsigned char& index));
应该是:
void generate(rgb_tuple (*predicate)(const unsigned char& index));
你不能传递函数!只是指向函数的指针。
但是唉! lambda只能转换为指向函数的指针,如果它们有一个空捕获集,而lambda则没有。
所以你可以试试std::function
:
void generate(std::function<rgb_tuple(const unsigned char& index)> predicate);
PS:有点解释是......你的错误信息是:
将参数1从'create_random_color_map ::'转换为'rgb_tuple(__ cdecl *)(const unsigned char&amp;)'不可能
第一部分create_random_color_map::
是告诉你它不知道它试图转换的对象类型的VC ++方式,但它是create_random_color_map
本地的东西:这显然是lambda本身。
第二部分rgb_tuple (__cdecl *)(const unsigned char &)
只是指向适当类型函数的指针。
错误说第一个不能转换为后者。