Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么visualc++;编译器在这里调用错误的重载? 为什么VisualC++编译器在这里调用错误的超载?< /P>_C++_Visual C++_Operator Overloading_Temporary - Fatal编程技术网

为什么visualc++;编译器在这里调用错误的重载? 为什么VisualC++编译器在这里调用错误的超载?< /P>

为什么visualc++;编译器在这里调用错误的重载? 为什么VisualC++编译器在这里调用错误的超载?< /P>,c++,visual-c++,operator-overloading,temporary,C++,Visual C++,Operator Overloading,Temporary,我有一个ostream的子类,用于定义格式化缓冲区。有时,我想创建一个临时文件,并立即使用通常的将字符串插入其中。我不确定您的代码是否应该编译。我认为: M2Stream & operator<<( void *vp ) M2Stream&operator问题在于您使用的是临时流对象。将代码更改为以下内容,它将正常工作: M2Stream ms; ms << "the string"; m2ms; MS > P>编译器做的是正确的事情:流():P>第一个问题是

我有一个ostream的子类,用于定义格式化缓冲区。有时,我想创建一个临时文件,并立即使用通常的将字符串插入其中。我不确定您的代码是否应该编译。我认为:

M2Stream & operator<<( void *vp )

M2Stream&operator问题在于您使用的是临时流对象。将代码更改为以下内容,它将正常工作:

M2Stream ms;
ms << "the string";
m2ms;

MS > P>编译器做的是正确的事情:<代码>流():P>第一个问题是由奇怪和棘手的C++语言规则引起的:

  • 通过调用构造函数创建的临时值是右值
  • 右值不能绑定到非常量引用
  • 但是,右值对象可以调用非常量方法

  • 发生的情况是,
    ostream&operator您可以使用如下重载:

    template <int N>
    M2Stream & operator<<(M2Stream & m, char const (& param)[N])
    {
         // output param
         return m;
    }
    
    模板
    

    M2Stream&Operator在VS 2003中对此进行了确认。我注意到,如果将void*vp更改为int*vp,就会得到预期的行为。在某些情况下,必须是某种隐式转换为void。我使用VS2008和VC6编译器编译了它。2008年,我得到了上述输出。但是使用VC6,我在第一次调用中也得到了const char*。令人惊讶。@Naveen:VC6错误地允许非常量引用绑定到临时变量——请参阅litb或我的答案,了解为什么这会导致事情“起作用”(尽管根据标准,它们实际上不应该起作用)。我不确定情况是否如此。如果我在我的电脑上把void*改为int*,它似乎能工作。“void*”很特别。大多数类型都可以转换为它,我猜VC也允许对“const char*”进行转换。如果您使用其他编译器进行上述更改,则代码将无法编译。请澄清(出于某些原因,我无法删除以前的注释)-另一个编译器无论如何都不会接受您编写的代码,因为将“const char”改为“void”是不标准的。+1。为流使用命名变量是最明智的解决方法(尽管感觉有点不雅观…),您关于第二种情况的不同转换的推理对我来说似乎是合理的。复制和粘贴失败-现在就尝试吧。好吧,它起作用是因为您删除了成员void*运算符。我没有那种奢望,因为我试图解决的最初问题是basic_ostream的一个子类,而basic_ostream有一个成员操作符,该操作符无效*所以我不能删除它。+1,像往常一样彻底:)但是你能解释一下做一些operator@j_random_hacker:这听起来像是个新问题!我对此也不确定:(至少在C++1x中,这些非常量引用将成为右值引用,因此我们可以实际传递临时流。另一个很好的解释是为什么右值不能绑定到非常量引用。这与您不能获取“地址”(apply&)的原因有关)另请注意,当我说“允许…绑定到临时值”时,我有点草率。我不得不说“允许…绑定到临时值”。它们并不完全相同。抛出的异常对象是临时值,但它们是左值,通常绑定到非常量引用:尝试{throw 10;}catch(int&r){…}临时值(未命名的抛出异常对象)存储在某个地方。它是一个左值,因此可以绑定到“int&r”。(它被称为临时对象,因为它只在异常处理过程中临时存在)。您在那里得到了一个很好的解释,我想我会给您+1:)谢谢!普通的ostream不会发生这种情况(或文字字符串将始终作为0x00123456指针输出)但它最初发生在我的basic_ostream子类中对不起,它确实发生在常规ostream中。以下输出十六进制地址:stringbuf b;ostream(&b)再次感谢您的明确解释。我在您和litb之间做出选择时遇到了困难,最终选择了他的答案是因为他对第二个问题的解释,但您的答案更清楚。@Carlos:不用担心,很高兴我能帮上忙。我过去曾在这个问题上撞过头!:)这可以在VC上运行,但不是标准的。临时的“M2Stream()”无法绑定到非常量引用:“M2Stream&m”。我在GCC上尝试过这个特定的代码段,但类似的函数在GCC和VC8上运行良好。
    M2Stream bad operator<<(void *) called with literal char string on constructed temporary
    M2Stream good operator<<(const char *) called with char string variable
    M2Stream good operator<<(const char *) called with literal char string on prebuilt object
    
    M2Stream & operator<<( void *vp )
    
    M2Stream & operator<<( const void *vp )
    
    #include <iostream>
    using namespace std;
    
    
    class M2Stream
    {
    };
    
    const M2Stream & operator<<( const M2Stream &os, const char *val)
    {
        cout << "M2Stream good operator<<(const char *) called with " << val << endl;
        return os;
    }
    
    
    int main(int argc, char argv[])
    {
        M2Stream() << "literal char string on constructed temporary";
    
        const char *s = "char string variable";
    
        // This line calls the const char * overload, and outputs: M2Stream good operator<<(const char *) called with char string variable
        M2Stream() << s;  
    
        // This line calls the const char * overload, and outputs: M2Stream good operator<<(const char *) called with literal char string on prebuilt object
        M2Stream m;
        m << "literal char string on prebuilt object";
        return 0;
    }
    
    M2Stream ms;
    ms << "the string";
    
    template <int N>
    M2Stream & operator<<(M2Stream & m, char const (& param)[N])
    {
         // output param
         return m;
    }