“错误 C3867:非标准语法;使用虚拟流操纵器时,使用“&”创建指向成员的指针

"Error C3867: non-standard syntax; use '&' to create a pointer to member" when using virtual stream manipulator

本文关键字:创建 使用 指针 成员 操纵 非标准 C3867 错误 语法 虚拟      更新时间:2023-10-16

>在Visual Studio 2015的代码中,我有接口:

struct IStr
{
    virtual std::ostream& beginMessage() = 0;
    virtual std::ostream& endMessage(std::ostream&) = 0;
};

我有一个实现这个接口的类,如下所示:

#include <sstream>
struct MyStr : public IStr
{
    std::stringstream m_stream;
    std::ostream& beginMessage() override { return m_stream; }
    std::ostream& endMessage(std::ostream& ss) override { return std::endl(ss); }
};

但是,我在尝试编译简单代码时遇到错误:

IStr * pStr = new MyStr();
pStr->beginMessage() << "Hello Wordl!" << pStr->endMessage;

附消息:

Error   C3867   
'IStr::endMessage': non-standard syntax; use '&' to create a pointer to member

真的很喜欢我尝试使用的语法。但这可能吗?也许问题是我的操纵器是虚拟的,还是非静态的?

使用 NVI,并endMessage()返回一个(有状态的)操纵器,该操纵器在流式传输时调用流上的虚拟函数。

struct IStr
{
    // other stuff
    private: 
    virtual std::ostream& doBeginMessage() = 0;
    virtual std::ostream& doEndMessage(std::ostream&) = 0;
    struct EndManip{
        IStr* istr;
    };
    friend std::ostream& operator<<(std::ostream& ss, EndManip em){
        return em.istr->doEndMessage(ss);
    }
    public:
    EndManip endMessage() { return {this}; }
    std::ostream& beginMessage() { return doBeginMessage(); }
};

有了这个,你会做pStr->beginMessage() << "Hello World!" << pStr->endMessage();.

你写过:

IStr * pStr = new MyStr();
pStr->beginMessage() << "Hello Wordl!" << pStr->endMessage;

虽然你应该写一些类似的东西:

IStr * pStr = new MyStr();
pStr->beginMessage() << "Hello Wordl!" << pStr->endMessage(*pStream);

这里的区别在于 (),这会导致执行函数调用而不是尝试传递指向函数的指针(这很可能不是您的意图)。