无法将右值参考函数与GCC匹配

问题描述 投票:3回答:1

[尝试使用右值引用时,我从GCC收到一个错误(clang不会产生错误)。

为什么编译器会产生错误?这是GCC中的错误吗?

“简化”错误是:

|In file included from /usr/include/c++/8/sstream:38,| from .code.tio.cpp:1:|/usr/include/c++/8/istream: In instantiation of 'struct std::__is_extractable<std::istream&, std::istream& (*&)(std::istream&, std::string&), void>':|/usr/include/c++/8/type_traits:131:12: required from 'struct std::__and_<std::__is_convertible_to_basic_istream<std::istringstream > >, std::__is_extractable<std::istream&, std::istream& (*&)(std::istream&, std::string&), void> >'|/usr/include/c++/8/type_traits:136:12: required from 'struct std::__and_<std::__not_<std::is_lvalue_reference<std::istringstream > > >, std::__is_convertible_to_basic_istream<std::istringstream > >, std::__is_extractable<std::istream&, std::istream& (*&)(std::istream&, std::string&), void> >'|/usr/include/c++/8/istream:980:5: required by substitution of 'template<class _Istream, class _Tp> typename std::enable_if<std::__and_<std::__not_<std::is_lvalue_reference<_Tp> >, std::__is_convertible_to_basic_istream<_Istream>, std::__is_extractable<typename std::__is_convertible_to_basic_istream<_Tp>::__istream_type, _Tp&&, void> >::value, typename std::__is_convertible_to_basic_istream<_Tp>::__istream_type>::type std::operator>>(_Istream&&, _Tp&&) [with _Istream = std::istringstream; _Tp = std::istream& (*&)(std::istream&, std::string&)]'|.code.tio.cpp:12:32: required from here|/usr/include/c++/8/istream:951:12: error: no match for 'operator>>' (operand types are 'std::istream' and 'std::istream& (*)(std::istream&, std::string&)')| __void_t<decltype(declval<_Istream&>()| ~~~~~~~~~~~~~~~~~~~~| >> declval<_Tp>())>>| ^~~~~~~~~~~~~~~~~

我尝试编译的代码是:

typedef std::istream &getline_type(std::istream &, std::string &);

void operator>>(std::istream &, getline_type) {}   // 1
void operator>>(std::istream &&, getline_type) {}

int main()
{
    std::string s;
    getline_type *getline = std::getline;          // 2
    //using std::getline;                          // 3
    std::istringstream("a") >> getline;
}

如果我注释掉标记为// 1的行,它将起作用。如果我使用标记为// 3的行而不是// 2,它也可以使用。

我相信clang正确地评估了代码的格式正确,但是如果有合理的理由拒绝该代码,则可能表明clang中存在错误。

Try it online!

c++ gcc overloading rvalue-reference
1个回答
1
投票

这确实是一个GCC错误:重载解析失败的line是特征partial specialization声明的一部分,因此替换失败应该具有消除“重载”(部分专业化),因此为特征生成false_type。然后,出于相同的原因,operator>>模板专门化本身将被消除,从而导致过多的负担。我认为GCC会将您的函数bleed放入查找集中(但仅部分保留,因为它毕竟会因为缺少istream&重载而拒绝)。

© www.soinside.com 2019 - 2024. All rights reserved.