Using std::make_pair with std::string (非右值引用问题)

Using std::make_pair with std::string (non rvalue reference problem)

std::pair<Url, std::string> UrlParser::parse()
{
    return std::make_pair({ extract_scheme(), extract_hostname(), extract_port(),
                 extract_path(), extract_filename() }, host_ip_);
}

host_ip_变量定义为

std::string host_ip_;

我明白了

UrlParser.cpp:91:64: error: no matching function for call to 'make_pair(<brace-enclosed initializer list>, std::string&)'
   91 |                  extract_path(), extract_filename() }, host_ip_);

问题出在 host_ip_ 变量上。如果是 std::string,那么退货有什么问题?

我发现 c++11 rvalue references in `std::make_pair` 这解释了我们不能用非右值引用调用 std::make_pair,所以我尝试了

std::make_pair({ extract_scheme(), extract_hostname(), extract_port(),
                     extract_path(), extract_filename() }, std::move(host_ip_));

但我明白了

error: no matching function for call to 'make_pair(<brace-enclosed initializer list>, std::remove_reference<std::__cxx11::basic_string<char>&>::type)'
   91 |                  extract_path(), extract_filename() }, std::move(host_ip_));

对了,为什么在link提供的int是一个右值引用而const int不是?

问题与将 host_ip_ 作为左值或右值传递给 std::make_pair; both should work fine. Instead, the braced-init-list { extract_scheme(), extract_hostname(), extract_port(), extract_path(), extract_filename() } makes template argument deduction for the 1st template paramter of std::make_pair failing because of non-deduced context 无关。

  1. The parameter P, whose A is a braced-init-list, but P is not std::initializer_list, a reference to one (possibly cv-qualified), or a reference to an array:

您可以显式传递 Url

return std::make_pair(Url{ extract_scheme(), extract_hostname(), extract_port(),
//                    ^^^
             extract_path(), extract_filename() }, host_ip_);

或明确指定模板参数。

return std::make_pair<Url>({ extract_scheme(), extract_hostname(), extract_port(),
//                   ^^^^^
//                   specify the 1st template argument, left the 2nd one to be deduced
             extract_path(), extract_filename() }, host_ip_);