使用std :: forward Forwarding重载函数

时间:2015-09-04 12:31:00

标签: c++ templates c++11 move-semantics perfect-forwarding

我想知道是否可以使用某些类型的约束进行转发,以便可以自动进行重载。例如,假设我有以下基本功能:

int f(A a, B b)
{
    return g(a) + h(b);
}

其中AB是包含所有正确的复制和移动构造函数的类,而gh是函数,每个函数都有两个重载:{{ 1}},int g(const A&)int g(A&&)相同。在h中转发ab的常用方法是

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只能绑定到{{1} }和T1,如果const A&A&&T1,则可以触发第二次重载?

如果没有这样的机制,我需要明确写出8个重载。

注意:我想我可能会在这个玩具示例中使用const B&中的一些模板做一些事情(有些讨厌),但我想首先知道是否有更简单的方法,因为在实际上,重载可能比这个玩具示例更加不同。

2 个答案:

答案 0 :(得分:4)

  

我可以约束T1和T2,这样在第一次重载时,T1只能绑定到_tempFilePath = AppDomain.CurrentDomain.BaseDirectory + TempDirectory; const A&吗?

是。这个概念被称为SFINAE(替代失败不是错误),基本上看起来像这样:

A&&

如果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); 没有&#34;腐烂&#34;到T1,那么A类型就会格式不正确,这种重载会被抛弃。

如果这太冗长,你可以写一个别名:

enable_if_t<>

答案 1 :(得分:1)

另一种可能性是根据类型

检索正确的参数

类似

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&