在 C++11 中,是否可以将模板函数包装在 std::function 中?
In C++11, is it possible to wrap a template function in a std::function?
如果我在 C++11 中有一个模板函数,是否可以将它包装在 std::function
中?
我的问题是这样的:
我有一个通用函数(比如求和函数),其中 return 类型取决于参数的类型:
template <typename T>
auto sum(T const& a, T const& b) -> decltype(a+b)
{
return a + b;
}
并且我想将它包装在 std:function
中以用于特定的参数类型(比如 int)。我正在尝试以下操作:
int main()
{
std::function<int(int,int)> intsum = std::bind(static_cast<int(*)(int,int)>(&sum), std::placeholders::_1, std::placeholders::_2);
auto mysum = intsum(2, 4);
std::cout << mysum << std::endl;
return 0;
}
但是编译上面的代码会产生错误:
error: invalid static_cast from type ‘<unresolved overloaded function type>’ to type ‘int (*)(int, int)
有什么方法可以实现我想要做的事情吗?
您可以专门化模板并使用它:
std::function<int(int,int)> intsum = sum<int>;
auto mysum = intsum(2, 4);
std::cout << mysum << std::endl;
您不能将通用函数包装在 std::function
的 特定实例中,这正是您所要求的。
但是,您可以包装通用函数的完全指定的 实例 ,这正是您的代码实际要执行的操作:
template <typename T>
auto sum(T const& a, T const& b) -> decltype(a+b)
{
return a + b;
}
#include <functional>
#include <iostream>
int main()
{
std::function<int(int,int)> intsum =
std::bind(sum<int>,
std::placeholders::_1, std::placeholders::_2);
auto mysum = intsum(2, 4);
std::cout << mysum << std::endl;
}
或者更简单地说
std::function<int(int,int)> intsum = sum<int>;
当然,如果您真的不需要 包装,只需:
auto mysum = sum(2, 4);
你的问题是类型错误。
sum<?>
没有 int(int,int)
重载。所以当你 static_cast<int(*)(int,int)(sum)
时,它会抱怨它无法进行转换。
存在 int(int const&,int const&)
过载。如果你 static_cast<int(*)(int const&, int const&)>(sum)
它会起作用。
如果没有这样的重载指向,函数模板到函数指针的转换将不起作用。
存在三种合理的方法。
首先,转换为正确的类型。 static_cast<int(*)(int const&,int const&)>(sum)
.
其次,明确的专业化。 sum<int>
而不是 static_cast
表达式。
三、创建重载集对象:
struct sum_t{
template<class...Args>
auto operator()(Args&&...args)const
-> decltype(sum(std::declval<Args>()...))
{
return sum(std::forward<Args>(args)...);
}
};
static sum_t sum_os;
并将 static_cast<int(*)(int,int)>(sum)
替换为 sum_os
。
sum_os
可以传递给 bind
或 std::function
或其他任何东西,重载决议被推迟到调用代码。
作为奖励,编译器比函数指针调用更容易优化。
作为负数,完美转发是不完美的。
重载集的 C++14 版本是:
[](auto&&...args)->
decltype(sum(decltype(args)(args)...))
{ return sum(decltype(args)(args)...); }
可以变成宏:
#define OVERLOAD_SET(FUNC) \
[](auto&&...args)-> \
decltype(FUNC(decltype(args)(args)...)) \
{ return FUNC(decltype(args)(args)...); }
这让您只需在使用时执行 OVERLOAD_SET(sum)
,然后传入整个重载集。
如果我在 C++11 中有一个模板函数,是否可以将它包装在 std::function
中?
我的问题是这样的:
我有一个通用函数(比如求和函数),其中 return 类型取决于参数的类型:
template <typename T>
auto sum(T const& a, T const& b) -> decltype(a+b)
{
return a + b;
}
并且我想将它包装在 std:function
中以用于特定的参数类型(比如 int)。我正在尝试以下操作:
int main()
{
std::function<int(int,int)> intsum = std::bind(static_cast<int(*)(int,int)>(&sum), std::placeholders::_1, std::placeholders::_2);
auto mysum = intsum(2, 4);
std::cout << mysum << std::endl;
return 0;
}
但是编译上面的代码会产生错误:
error: invalid static_cast from type ‘<unresolved overloaded function type>’ to type ‘int (*)(int, int)
有什么方法可以实现我想要做的事情吗?
您可以专门化模板并使用它:
std::function<int(int,int)> intsum = sum<int>;
auto mysum = intsum(2, 4);
std::cout << mysum << std::endl;
您不能将通用函数包装在 std::function
的 特定实例中,这正是您所要求的。
但是,您可以包装通用函数的完全指定的 实例 ,这正是您的代码实际要执行的操作:
template <typename T>
auto sum(T const& a, T const& b) -> decltype(a+b)
{
return a + b;
}
#include <functional>
#include <iostream>
int main()
{
std::function<int(int,int)> intsum =
std::bind(sum<int>,
std::placeholders::_1, std::placeholders::_2);
auto mysum = intsum(2, 4);
std::cout << mysum << std::endl;
}
或者更简单地说
std::function<int(int,int)> intsum = sum<int>;
当然,如果您真的不需要 包装,只需:
auto mysum = sum(2, 4);
你的问题是类型错误。
sum<?>
没有 int(int,int)
重载。所以当你 static_cast<int(*)(int,int)(sum)
时,它会抱怨它无法进行转换。
存在 int(int const&,int const&)
过载。如果你 static_cast<int(*)(int const&, int const&)>(sum)
它会起作用。
如果没有这样的重载指向,函数模板到函数指针的转换将不起作用。
存在三种合理的方法。
首先,转换为正确的类型。 static_cast<int(*)(int const&,int const&)>(sum)
.
其次,明确的专业化。 sum<int>
而不是 static_cast
表达式。
三、创建重载集对象:
struct sum_t{
template<class...Args>
auto operator()(Args&&...args)const
-> decltype(sum(std::declval<Args>()...))
{
return sum(std::forward<Args>(args)...);
}
};
static sum_t sum_os;
并将 static_cast<int(*)(int,int)>(sum)
替换为 sum_os
。
sum_os
可以传递给 bind
或 std::function
或其他任何东西,重载决议被推迟到调用代码。
作为奖励,编译器比函数指针调用更容易优化。
作为负数,完美转发是不完美的。
重载集的 C++14 版本是:
[](auto&&...args)->
decltype(sum(decltype(args)(args)...))
{ return sum(decltype(args)(args)...); }
可以变成宏:
#define OVERLOAD_SET(FUNC) \
[](auto&&...args)-> \
decltype(FUNC(decltype(args)(args)...)) \
{ return FUNC(decltype(args)(args)...); }
这让您只需在使用时执行 OVERLOAD_SET(sum)
,然后传入整个重载集。