Template accepts const but not literal

荒凉一梦 提交于 2019-12-06 16:41:30

int literals have type int, not const int. T is therefore deduced to be int, and int& can't bind to a prvalue.

The correct way to write such a function is to either perfect forward the arguments, or use const T&, both of which can bind to anything.

template<typename T, typename U>
auto min(T&& a, U&& b) -> decltype(a < b ? std::forward<T>(a) : std::forward<U>(b))
{
    return a < b ? std::forward<T>(a) : std::forward<U>(b); 
}

// Or...
template<typename T>
const T& min(const T& a, const T& b)
{
    return a < b ? a : b;
}

In the case of perfectly forwarding the arguments, the two template parameters are needed in order for int a{}; min(a, 42); to compile, as their deduced types are different.

Isn't an int literal a const int?

No, it is just an int, not const, and is defined as a prvalue, hence an lvalue reference cannot bind to it -- as is in your case.

Easily corrected by having the original template like this:

template<typename T>
const T& min(const T& a, const T& b){
    return a < b ? a : b;
}

as const T& will bind to rvalues as well.

Avoid changing to or adding anything the likes of this:

template<typename T, typename U>
auto&& min(T&& a, U&& b){
    return std::forward<T>(a < b ? a : b); 
}

as here we do not create a copy from the materialized temporary, and as such we're at the risk of returning a dangling reference. See here in [class.temporary]:

A temporary object bound to a reference parameter in a function call ([expr.call]) persists until the completion of the full-expression containing the call.

... at which point it dies. Hence the dangling-ness.

Literal produces a prvalue expression which T& can not accept. T& accepts only lvalues.

You can think about it this way: integral literal is a "non-living" thing as it has no address anywhere, how could you bind it to the lvalue reference and then modify it? Where that object would be located? Where the changes would be written?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!