为什么下面的 std::transform 示例需要函数指针而不是函数对象?
Why does the following `std::transform` example need a function pointer instead of a function object?
函数模板std::transform()
接受一个范围,使用运算符对其进行组件操作,并将结果保存在另一个范围中。在下面的示例中,该函数接受一个名为 nl
的通用 std::initializer_list
并使用 (std::string (*)(T)) std::to_string
对其进行操作以将其所有条目转换为字符串,然后将结果存储在一个名为buffer
.
class num_list
{
public:
template<typename T>
num_list(std::initializer_list<T> nl):
size{nl.size()},
buffer(new std::string[size])
{
std::transform(nl.begin(), nl.end(), // input sequence
buffer, // output result
(std::string (*)(T))std::to_string); // unary operator
}
//...
private:
std::size_t size;
std::string * buffer;
};
我想知道为什么我们需要将 std::to_string
类型转换为函数指针才能使其工作。如果我们放弃对函数指针类型 (std::string (*)(T))
的强制转换,为什么代码无法使用 C++11 进行编译?我无法解读编译器抛出的抱怨。
error: no instance of overloaded function "std::transform" matches the argument list
std::transform
是一个函数模板,它通过模板参数类型获取函数对象。由于类型是模板参数,因此必须推导它。 std::to_string
是一个重载函数,因此当您尝试推断其类型时,您会得到多个结果。由于推导中没有其他任何东西可以帮助缩小类型范围,编译器将无法推导出 std::to_string
的类型,您将得到一个错误。
当您将 std::to_string
转换为 std::string (*)(T)
时,您现在只有单一类型供编译器推断,它确实如此,并且您可以成功编译。
您可以使用通用 lambda 代替转换,而不是像
那样转发到 std::to_string
std::transform(nl.begin(), nl.end(), // input sequence
buffer, // output result
([](auto&& val){ return std::to_string(val);});
但这至少需要 C++14。对于 C++11,您可以使用 T
作为参数类型,例如
std::transform(nl.begin(), nl.end(), // input sequence
buffer, // output result
([](const T& val){ return std::to_string(val);});
函数模板std::transform()
接受一个范围,使用运算符对其进行组件操作,并将结果保存在另一个范围中。在下面的示例中,该函数接受一个名为 nl
的通用 std::initializer_list
并使用 (std::string (*)(T)) std::to_string
对其进行操作以将其所有条目转换为字符串,然后将结果存储在一个名为buffer
.
class num_list
{
public:
template<typename T>
num_list(std::initializer_list<T> nl):
size{nl.size()},
buffer(new std::string[size])
{
std::transform(nl.begin(), nl.end(), // input sequence
buffer, // output result
(std::string (*)(T))std::to_string); // unary operator
}
//...
private:
std::size_t size;
std::string * buffer;
};
我想知道为什么我们需要将 std::to_string
类型转换为函数指针才能使其工作。如果我们放弃对函数指针类型 (std::string (*)(T))
的强制转换,为什么代码无法使用 C++11 进行编译?我无法解读编译器抛出的抱怨。
error: no instance of overloaded function "std::transform" matches the argument list
std::transform
是一个函数模板,它通过模板参数类型获取函数对象。由于类型是模板参数,因此必须推导它。 std::to_string
是一个重载函数,因此当您尝试推断其类型时,您会得到多个结果。由于推导中没有其他任何东西可以帮助缩小类型范围,编译器将无法推导出 std::to_string
的类型,您将得到一个错误。
当您将 std::to_string
转换为 std::string (*)(T)
时,您现在只有单一类型供编译器推断,它确实如此,并且您可以成功编译。
您可以使用通用 lambda 代替转换,而不是像
那样转发到std::to_string
std::transform(nl.begin(), nl.end(), // input sequence
buffer, // output result
([](auto&& val){ return std::to_string(val);});
但这至少需要 C++14。对于 C++11,您可以使用 T
作为参数类型,例如
std::transform(nl.begin(), nl.end(), // input sequence
buffer, // output result
([](const T& val){ return std::to_string(val);});