代码之家  ›  专栏  ›  技术社区  ›  Ivan Rubinson

模板接受常量,但不接受文本

  •  1
  • Ivan Rubinson  · 技术社区  · 7 年前

    在编写模板时, class T const 类型。

    考虑:

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

    这将在以下情况下起作用:

    int a = 1, b = 5;
    const int c = 1, d = 5;
    min(a, b); // T is int
    min(c, d); // T is const int
    

    但在使用文本调用时会抛出编译错误(如下所示):

    min(1, 5); // T is const int literal
    

    为什么?整型文字不是 const int ? 如何修改模板以允许使用文本?

    (符合gcc 6.3和MSVC 2015)

    3 回复  |  直到 7 年前
        1
  •  3
  •   Passer By    7 年前

    int 文字具有类型 内景 ,不是 const int . T 因此推断为 ,和 int& can't bind to a prvalue .

    编写这样一个函数的正确方法是要么完美地转发参数,要么使用 const T& ,两者都可以绑定到任何东西。

    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;
    }
    

    在完全转发参数的情况下,需要使用两个模板参数来 int a{}; min(a, 42);

        2
  •  2
  •   Geezer    7 年前

    整型文字不是常量整型吗?

    不,它只是一个 int ,不是 const ,和 is defined as a prvalue ,因此 左值引用 无法绑定到它--就像您的情况一样。

    使用如下原始模板可以轻松更正:

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

    作为 const T& 将绑定到 他也是。

    避免更改或添加类似的内容:

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

    悬挂参考 [class.temporary] :

    ([表达式调用])持续到完整表达式完成

    ... 在这一点上它就死了。因此就有了悬空。

        3
  •  0
  •   ixSci    7 年前

    T& 不能接受。 T& 只接受左值。