为什么 std::p air<int, int> 可以从 const std::p air<int, float>& 构造?

Why is std::pair<int, int> constructible from a const std::pair<int, float>&?

本文关键字:int air std gt lt float 构造 const 为什么      更新时间:2023-10-16

似乎std::pair<int, int>可以使用此处的第4个定义从const std::pair<int, float>&隐式构造。

#include <iostream>
#include <vector>
#include <utility>
int main() {
    std::vector<std::pair<int, float>> v = { {1, 1.5f} };
    // The interesting line:
    const std::pair<int, int>& x = v[0];
    const auto& y = v[0];
    std::cout << "before:n";
    std::cout << "tv[0]: " << std::get<1>(v[0]) << "n";
    std::cout << "tx:    " << std::get<1>(x) << "n";
    std::cout << "ty:    " << std::get<1>(y) << "n";
    std::get<1>(v[0]) = 3.5f;
    std::cout << "nafter:n";
    std::cout << "tv[0]: " << std::get<1>(v[0]) << "n";
    std::cout << "tx:    " << std::get<1>(x) << "n";
    std::cout << "ty:    " << std::get<1>(y) << "n";
}

输出为

before:
    v[0]: 1.5
    x:    1
    y:    1.5
after:
    v[0]: 3.5
    x:    1
    y:    3.5

(视频链接)

y相比,x"感觉"不像是一个引用,这似乎很尴尬(因为从用户的角度来看,它(合法地)引用了可能是"错误"的东西。)

该构造函数未标记为explicit的理由是什么?(我假设有一个重要的用例。)

// The interesting line:
const std::pair<int, int>& x = v[0];

该代码相当于:

const std::pair<int,int>& x = std::pair<int,int>(v[0]);

让您感到惊讶的问题是,由于存在从std::pair<int,float>std::pair<int,int>的转换,编译器被允许(并且被要求)创建一个临时的并将const引用绑定到它。如果删除const(并且没有使用VS),则代码应该会失败。

x不是对v[0]的引用,而是对与x的生存期匹配的类型为std::pair<int, int>的对象的引用。初始化const T&时,如果无法直接引用,则将从右侧构造一个新对象。

在这种情况下,你写的内容与写的内容相同:

const std::pair<int, int> x = v[0]; // note: no reference

不过,由于float到int的转换,您可能应该得到一个警告。