C++ 如何省略C+中不同参数的复制函数定义+;

C++ 如何省略C+中不同参数的复制函数定义+;,c++,parameter-passing,c++14,C++,Parameter Passing,C++14,我有很多代码以某种方式执行完全相同的操作(继承的代码),我希望在重新编写代码时,压缩代码而不丢失功能。例如,让我们看一下以下函数: fnc(largetype & a, largetype & b) { f(A); f(B); }; fnc(largetype && a, largetype & b) { f(A); f(B); }; fnc(largetype & a, largetype && b) { f(A); f(

我有很多代码以某种方式执行完全相同的操作(继承的代码),我希望在重新编写代码时,压缩代码而不丢失功能。例如,让我们看一下以下函数:

fnc(largetype & a,  largetype & b)  { f(A); f(B); };
fnc(largetype && a, largetype & b)  { f(A); f(B); };
fnc(largetype & a,  largetype && b) { f(A); f(B); };
fnc(largetype && a, largetype && b) { f(A); f(B); };
它们都在做完全相同的事情,但参数可以是右值或左值,而不会破坏函数逻辑。我想允许用户传递适合问题的任何内容,但我也不想逐段复制粘贴所有代码。我可以这样做:

fnc(largetype & a,  largetype & b)  { f(A); f(B); };
fnc(largetype && a, largetype & b)  { fnc(a,b) };
fnc(largetype & a,  largetype && b) { fnc(a,b) };
fnc(largetype && a, largetype && b) { fnc(a,b) };
这在技术上是正确的,尤其是内联,但在我看来是错误的。有没有其他更好的方法来达到这样的效果

唯一的要求是作为参数传递的类型可能/将以某种方式大于默认内存块大小,因此避免复制至关重要。此外,参数可能更小,但也可能是右值,这是非零的可能性。线程安全是可选的


我考虑过将这些函数模板化,但我认为这也是一种错误的方法。模板解决不同接受类型的问题。在我的例子中,类型是相同的,只是以不同的方式传递。

正如@SamVarshavchik所评论的,这是完美转发的常见候选。一个简单的方法:

template<typename T, typename U>
void fnc(T&& a, U&& b)
{
    f(std::forward<T>(a));
    f(std::forward<U>(b));
}

或者,您可能希望将错误站点保留在
fnc
中,但给出更清晰的错误消息–这可以通过
static\u assert
实现:

template<typename T, typename U>
void fnc(T&& a, U&& b)
{
    static_assert(std::is_same<std::decay_t<T>, largetype>{},
                  "argument 'a' must be of type 'largetype'");
    static_assert(std::is_same<std::decay_t<U>, largetype>{},
                  "argument 'b' must be of type 'largetype'");

    f(std::forward<T>(a));
    f(std::forward<U>(b));
}
模板
无效fnc(T&a、U&b)
{
静态断言(std::is_same{},
“参数'a'必须是'largetype'类型”;
静态断言(std::is_same{},
“参数'b'必须是'LarGetType'类型”;
f(标准:远期(a));;
f(标准:远期(b));;
}

将模板函数与。。。
template<typename T, typename U>
void fnc(T&& a, U&& b)
{
    static_assert(std::is_same<std::decay_t<T>, largetype>{},
                  "argument 'a' must be of type 'largetype'");
    static_assert(std::is_same<std::decay_t<U>, largetype>{},
                  "argument 'b' must be of type 'largetype'");

    f(std::forward<T>(a));
    f(std::forward<U>(b));
}