在c++11之前,我曾经写过这样的代码:
// Small functions
void doThingsWithA(const A& a)
{
// do stuff
}
void doThingsWithB(const B& b)
{
// do stuff
}
void doThingsWithC(const C& c)
{
// do stuff
}
// Big function
void doThingsWithABC(const A& a, const B& b, const C& c)
{
// do stuff
doThingsWithA(a);
doThingsWithB(b);
doThingsWithC(c);
// do stuff
}
但是现在,有了移动语义,允许我的函数将右值引用作为参数并添加这些重载可能会变得有趣(至少在某些情况下):
void doThingsWithA(A&& a);
void doThingsWithB(B&& b);
void doThingsWithC(C&& c);
从我收集到的信息来看,如果我希望能够在我的大函数中调用这些重载,我需要使用完美转发,它可能看起来像这样(它的可读性有点低,但我想它可以用模板类型的良好命名约定):
template<typename TplA, typename TplB, typename TplC>
void doThingsWithABC(TplA&& a, TplB&& b, TplC&& c)
{
// do stuff
doThingsWithA(std::forward<TplA>(a));
doThingsWithB(std::forward<TplB>(b));
doThingsWithC(std::forward<TplC>(c));
// do stuff
}
我的问题是这样的:这是否意味着如果我的小函数有其他重载,就可以使用不打算使用的类型参数调用大函数?
我认为这可能有助于防止这种情况:
template<typename TplA, typename TplB, typename TplC,
class = typename std::enable_if<std::is_same<A, std::decay<TplA>::type>::value>::type,
class = typename std::enable_if<std::is_same<B, std::decay<TplB>::type>::value>::type,
class = typename std::enable_if<std::is_same<C, std::decay<TplC>::type>::value>::type>
doThingsWithABC(TplA&& a, TplB&& b, TplC&& c)
{
// do stuff
doThingsWithA(std::forward<TplA>(a));
doThingsWithB(std::forward<TplB>(b));
doThingsWithC(std::forward<TplC>(c));
// do stuff
}
虽然我不确定它是否不太严格,因为如果我尝试使用可隐式转换为 A、B 或 C 的类型调用大函数,我不知道它的行为...
但是......即使假设这有效,我真的没有其他选择吗?(我的意思是......这对眼睛来说并不容易)