我想知道是否可以使用某些类型的约束进行转发,以便可以自动进行重载。例如,假设我有以下基本功能:
int f(A a, B b)
{
return g(a) + h(b);
}
其中A
和B
是包含所有正确的复制和移动构造函数的类,而g
和h
是函数,每个函数都有两个重载:{{ 1}},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
只能绑定到{{1} }和T1
,如果const A&
为A&&
或T1
,则可以触发第二次重载?
如果没有这样的机制,我需要明确写出8个重载。
注意:我想我可能会在这个玩具示例中使用const B&
中的一些模板做一些事情(有些讨厌),但我想首先知道是否有更简单的方法,因为在实际上,重载可能比这个玩具示例更加不同。
答案 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&
。