使用 std::转发的重载函数
Overloading Functions with std::forward Forwarding
我想知道是否可以在对类型进行一些约束的情况下进行转发,以便可以自动重载。例如,假设我有以下基本函数:
int f(A a, B b)
{
return g(a) + h(b);
}
其中A
和B
是包含所有正确复制和移动构造函数的类,g
和h
是函数,每个函数都有两个重载:int g(const A&)
、int g(A&&)
和h
相同。转发a
和b
的通常方法是 f
template <typename T1, typename T2>
int f(T1&& a, T2&& b)
{
return g(std::forward<T1>(a)) + h(std::forward<T2>(b));
}
但是,我还想添加另一种使用此功能的方法:
int f(B b, A a)
{
return g(a) + h(b);
}
如果我尝试在此重载中使用转发,则生成的模板函数如下所示:
template <typename T1, typename T2>
int f(T1&& b, T2&& a)
{
return g(std::forward<T1>(a)) + h(std::forward<T2>(b));
}
这将与第一个模板冲突。
所以我的问题是,当我编写一个用于转发的模板函数时,我是否可以约束T1
和T2
,以便在第一次重载中,T1
只能绑定到const A&
和A&&
,而第二次重载可以在T1
const B&
或B&&
时触发?
如果没有这样的机制,我需要显式编写 8 个重载。
注意:我想我可以用这个玩具示例中type_traits
的一些模板做一些事情(有点讨厌(,但我首先想知道是否有更简单的方法,因为实际上,重载可能比这个玩具示例更不同。
我可以约束 T1 和 T2 以便第一次重载时,T1 只能绑定到
const A&
和A&&
吗?
是的。这个概念被称为SFINAE(替换失败不是错误(,基本上看起来像这样:
template <typename T1, typename T2,
std::enable_if_t<std::is_same<A, std::decay_t<T1>>::value>* = nullptr
>
int f(T1&& a, T2&& b);
如果T1
没有"衰减"到A
,那么enable_if_t<>
类型将是格式不正确的,并且这个重载将被抛弃。
如果太冗长,您可以编写别名:
template <typename From, typename To>
using enable_if_decays = std::enable_if_t<std::is_same<To, std::decay_t<From>>::value>;
template <typename T1, typename T2,
enable_if_decays<T1, A>* = nullptr>
int f1(T1&& a, T2&& b);
template <typename T1, typename T2,
enable_if_decays<T1, B>* = nullptr>
int f1(T1&& b, T2&& a);
// etc.
另一种可能性是根据其类型检索正确的参数
类似的东西
template <typename T1, typename T2>
int f(T1&& t1, T2&& t2)
{
auto t = std::forward_as_tuple(t1, t2);
return g(my_get<A>(t)) + h(my_get<B>(t));
}
my_get<T>
类似于std::get<T>(TUPLE&)
,但检索T&&
或T&
,具体取决于元组内容类型。
相关文章:
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 可以打印矢量和矢量中的矢量的非重载C++函数
- 错误 没有与参数列表匹配的重载函数"getline"实例
- 使用模板重载函数
- C++线程中,没有重载函数接受 X 参数
- std::vector 没有重载函数的实例与参数列表匹配
- C++重载函数,一个采用基类的参数,另一个采用派生类的参数
- 错误:无法解析对重载函数的引用;你的意思是调用它吗?
- 对重载函数find_first_not_of的不明确调用
- 如何从重载解析中删除重载函数?
- CUDA:重载函数"isnan"的多个实例
- C++派生类重载函数(带有 std::function 参数)不可见
- 避免在人为的重载函数调用中拼写出类型
- C++:如何为多个重载函数保留通用代码路径?
- 什么时候可以使用常量装饰调用我的重载函数?
- 尝试使用谓词函数会导致错误:"std::sort"未找到匹配的重载函数
- std::调用,未找到匹配的重载函数
- 为什么在传递长整型时调用具有两个双精度类型的参数的重载函数?
- 为什么使用不匹配的参数调用重载函数仍然有效
- 如何通过签名作为模板参数来解决重载函数?