具体类型的通用参考

时间:2014-11-04 18:58:04

标签: c++

我希望函数具有带有具体类型的通用引用参数。我希望它是通用引用,所以当我对检查存储在其中的值不感兴趣时​​,我可以传递一个临时对象。

以下是示例:

bool bCompareData(const uint8_t *arg_0, const uint8_t *arg_1, size_t &szComparedData)
{
    size_t &i = szComparedData;

    for (; arg_1[i]; ++i)
        if (arg_1[i] != arg_0[i])
            return false;

    return true;
}

可能的函数调用:

bCompareData(Obj.uIdObject.data(), Ref.uIdTargetObject.data(), size_t()) // here we are passing a temporary (rvalue)
/*________________________*/ 
size_t lval;
bCompareData(Obj.uIdObject.data(), Ref.uIdTargetObject.data(), lval) // here we are passing a named variable (lvalue)

如果我改变" size_t& szComparedData"在第一个函数调用编译器中使用上述函数声明将给出错误。估价参考" size_t&& szComparedData"它会在第二次通话时失败。

现在我需要的是Universal References,但我也希望在我的论证中有一个具体的类型,而不是使用模板。

我正在使用VC ++ U3 2013编译器。

3 个答案:

答案 0 :(得分:5)

通用引用仅根据定义使用模板和类型推导。您只能使用SFINAE来限制对特定类型的引用:

template< typename S >
typename std::enable_if<
    std::is_same<typename std::decay<S>::type,size_t>::value,
bool>::type
bCompareData(const uint8_t *arg_0, const uint8_t *arg_1, S&& szComparedData)
{
    // ...
}

或者,如果确实需要避免使用模板,则需要重载方法:

bool bCompareData(const uint8_t *arg_0, const uint8_t *arg_1, size_t& szComparedData)
{
    // ...
}

bool bCompareData(const uint8_t *arg_0, const uint8_t *arg_1, size_t&& szComparedData)
{
    // ...
}

答案 1 :(得分:2)

不能使用通用引用而不使用模板,因为“通用引用”是模板的事情。你想要的是能够传递左值或右值,这可以在没有模板的情况下完成。

这里正确的工具是重载。有趣的是,这只需要一个非常简单的过载。

bool bCompareData(const uint8_t *arg_0, const uint8_t *arg_1, size_t &szComparedData)
{
    size_t &i = szComparedData;

    for (; arg_1[i]; ++i)
        if (arg_1[i] != arg_0[i])
            return false;

    return true;
}
bool bCompareData(const uint8_t *arg_0, const uint8_t *arg_1, size_t &&szComparedData)
{ return bCompareData(arg_0, arg_1, szComparedData);}

这是有效的,因为函数参数列表中的&&告诉该函数参数是来自右值的构造,但所有命名值本身都是左值。由于它有名称,它是一个左值,你可以简单地将它传递给现有的函数。

答案 2 :(得分:0)

或者我后来做了什么,我认为这不是最好的解决方案:

template <typename T = size_t>

inline bool bCompareData(const uint8_t *arg_0, const uint8_t *arg_1, T &&arg_2 = size_t())
{
    arg_2 = 0;

    extern bool _bCompareData(const uint8_t *, const uint8_t *, size_t &); //compare data

    return _bCompareData(arg_0, arg_1, arg_2);
}

C ++是一种非常奇怪的语言。我指的是'rvalue'和&amp; '左值'引用具有相同的大小和属性,因此它们是如何变成不同类型的。