C++ 为什么重载运算符上的异常说明符'<<';不';不适用于任何std::ostream对象,但是否适用于库中定义的对象?

C++ 为什么重载运算符上的异常说明符'<<';不';不适用于任何std::ostream对象,但是否适用于库中定义的对象?,c++,c++11,constexpr,noexcept,C++,C++11,Constexpr,Noexcept,examplo.cpp: #include <type_traits> using std::is_same; #include <utility> using std::declval; #include <iostream> using std::ostream; using std::cout; struct Foo final { int value; inline constexpr Foo(const int i) noexc

examplo.cpp:

#include <type_traits>
using std::is_same;

#include <utility>
using std::declval;

#include <iostream>
using std::ostream;
using std::cout;

struct Foo final {
    int value;
    inline constexpr Foo(const int i) noexcept : value{i} {};
    inline ~Foo() = default;
};

ostream& operator<<(ostream& out, const Foo& foo) noexcept { return out << foo.value; }

int main() {
    const Foo a(42);
    static_assert(is_same<decltype(cout), ostream>::value == true, ""); // assert always to true...

    static_assert(noexcept(cout << a) == true, ""); // assert to true if the operator on line 21 is defined noexcept(true)

    static_assert(noexcept(declval<ostream>() << a) == true, ""); // assert always to false...

    static_assert(noexcept(declval<decltype(cout)>() << a) == true, ""); // Same as line 32...

    return 0;
}
错误:

exemplo.cpp:32:53: error: static assertion failed
    static_assert( noexcept( declval<ostream>() << a) == true, ""); // assert always to false...
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
exemplo.cpp:34:60: error: static assertion failed
    static_assert( noexcept( declval<decltype(cout)>() << a) == true, ""); // same as line 32
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
exemplo.cpp:32:53:错误:静态断言失败

static_assert(noexcept(declval()原因是
declval
生成一个临时对象,因此如果您的代码有另一个重载,如下所示

ostream& operator<<(ostream&& out, const Foo& foo) noexcept { return out << foo.value; }

ostream&operator原因是
declval
生成一个临时对象,因此如果您的代码有另一个重载,就像这样

ostream& operator<<(ostream&& out, const Foo& foo) noexcept { return out << foo.value; }

ostream&operator您不能将prvalue
ostream
绑定到
ostream&
,而应该使用
ostream&
表达式

int main() {
    const Foo a(42);
    static_assert(is_same<decltype(cout), ostream>::value == true, ""); 

    static_assert(noexcept(cout << a) == true, "");

    static_assert(noexcept(declval<ostream&>() << a) == true, "");

    static_assert(noexcept(declval<decltype(cout)&>() << a) == true, ""); 

    return 0;
}
intmain(){
康富阿(42),;
静态断言(is_same::value==true,“”);

static_assert(noexcept)(cout您不能将prvalue
ostream
绑定到
ostream&
,而是应该有一个
ostream&
表达式

int main() {
    const Foo a(42);
    static_assert(is_same<decltype(cout), ostream>::value == true, ""); 

    static_assert(noexcept(cout << a) == true, "");

    static_assert(noexcept(declval<ostream&>() << a) == true, "");

    static_assert(noexcept(declval<decltype(cout)&>() << a) == true, ""); 

    return 0;
}
intmain(){
康富阿(42),;
静态断言(is_same::value==true,“”);

静态断言(无例外(请不要发布文本和代码的图像。复制粘贴代码并创建一个副本,同时粘贴您收到的错误消息。好的。但是完整的解释将占用36行以上的内容。请不要发布文本和代码的图像。复制粘贴代码并创建一个副本,同时粘贴您收到的错误消息。好的。但是完整的解释ion将占用超过36行。谢谢。我没有忘记declval()返回t&&(右值引用),但我认为一旦没有其他类似的重载,它就会工作,或者至少会生成一个不同的编译错误,比如:没有这样的签名调用的函数。谢谢。我没有忘记declval()返回t&(右值引用),但我认为一旦没有其他类似的重载,它就会工作,或者至少会生成一个不同的编译错误,比如:没有使用这种签名调用的函数。