在C++中传递内联临时类需要const。如何解决这个问题

在C++中传递内联临时类需要const。如何解决这个问题,c++,c++11,temporary-objects,C++,C++11,Temporary Objects,我想用c++11为不同的CPU(实际上是MCU)编写可移植代码。由于某些CPU不支持通过其内存地址空间(如Atmel AVR)直接读取程序数据,因此我需要一种解决方案,该解决方案使用直接地址或自定义流指针调用函数,以通过某些外部存储器读取数据 将此代码视为自定义库: class IStream { public: virtual char ReadChar(); }; class ConstMemoryStream : public IStream { const char*

我想用c++11为不同的CPU(实际上是MCU)编写可移植代码。由于某些CPU不支持通过其内存地址空间(如Atmel AVR)直接读取程序数据,因此我需要一种解决方案,该解决方案使用直接地址或自定义流指针调用函数,以通过某些外部存储器读取数据

将此代码视为自定义库:

class IStream
{
    public: virtual char ReadChar();
};

class ConstMemoryStream : public IStream
{
    const char* Position;

    public: ConstMemoryStream(const char* startAddress)
    {
        Position = startAddress;
    }

    public: char ReadChar() override
    {
        return *Position++;
    }
};

void Send(char data) { } // Send data to serial port
现在,我想实现一个函数,该函数采用内存地址或流来读取数据:

// const parameter is needed here, otherwise error: invalid initialisation of non-const reference of type 'IStream&' from an rvalue of type 'IStream'
void PrintMessage(const IStream& stream)
{
    while (true) // TODO: end condition
        //Send(stream.ReadChar());  // this gives an error because i need to use a const parameter: passing 'const IStream' as 'this' argument discards qualifiers
        Send( ((IStream*)&stream)->ReadChar() );  // this works, this actually bypass the error above. IS THIS OK?????
}

void PrintMessage(char* address); // overload to use memory instead of stream. implementation not important here
接下来,我想用流调用PrintMessage,但这个流需要内联创建,在PrintMessage函数之外不再需要:

int main(void)
{
    // Requirement: ConstMemoryStream needs to be created and passed INLINE PrintMessage
    PrintMessage(ConstMemoryStream("Hello!")); // This works only if i put const in PrintMessage parameter.
}
上面的所有代码都可以编译并运行,但我主要关心的是,我需要在PrintMessage函数中使用const参数,否则会出现错误。因此,我需要做一个丑陋的演员:

Send( ((IStream*)&stream)->ReadChar() );
这基本上使参数非常量,以避免错误。但是,有没有更好的办法来合法地解决这个问题呢

流实例本身不能是const,因为它在内部推进它的位置,但是C++需要将它作为const传递,因为它是内联的临时变量,它总是被视为rValue.< 我看不出临时变量修改自己有什么害处,在PrintMessage函数返回后,它还是被丢弃了

我最终想要做的内联要求是:

#ifdef CPU_AVR
    #define CSTR(str) ConstMemoryStream(PROGMEM str) // the PROGMEM attribute puts the text in a separate space not accessible in regular memory
#elif defined CPU_SAM
    #define CSTR(str) (char*)str
#endif

int main2(void)
{
    // If the CPU does not support direct address mapping to it's FLASH space, pass a stream instead of a direct memory pointer
    PrintMessage(CSTR("Hello"));
}

有没有关于如何正确地做到这一点,而不铸造放弃错误的想法?或者上面的当前代码可以接受吗?

对于C++11,只需将右值引用作为参数即可

void PrintMessage(IStream && stream)

右值引用将绑定到临时引用,在这种情况下,右值引用与左值引用几乎无法区分。

使用C++11,您可以简单地将右值引用作为参数

void PrintMessage(IStream && stream)

右值引用将绑定到临时引用,在这种情况下,右值引用与左值引用基本上无法区分。

要么界面错误,要么用法错误。目前,您正在const_铸造您的流。如果您曾经传递一个const IStream对象,那将是未定义的行为

要么:

class IStream
{
    public: virtual char ReadChar() const;
};
或:


要么你的界面错了,要么你的用法错了。目前,您正在const_铸造您的流。如果您曾经传递一个const IStream对象,那将是未定义的行为

要么:

class IStream
{
    public: virtual char ReadChar() const;
};
或:


你的编译器支持C++11或更高版本吗?是的,它是C++11更新了我的questionconst IStream&stream为什么要使它为const?只要做一个裁判,一切都很好。这与AVR无关,因为据我所知,STL不适用于AVR。如果你有AVR的STL,请告诉我@Bigjim,Sam的答案似乎解决了你的问题,不是吗?@anastaciu事实上,传递构造的对象不是一个选项,因为我需要将它与宏内联使用。你的编译器支持C++11或更高版本吗?是的,它是C++11更新了我的questionconst IStream&stream为什么要将其设置为const?只要做一个裁判,一切都很好。这与AVR无关,因为据我所知,STL不适用于AVR。如果你有AVR的STL,请告诉我@Bigjim,Sam的答案似乎解决了你的问题,不是吗?@anastaciu事实上,传递构造的对象不是一个选项,因为我需要将它与宏内联使用。这正是我想要的。谢谢这正是我想要的。谢谢事实上,我知道我的用法是错误的,这就是我问如何正确使用的原因。IStream&&是解决方案,如第二个示例所示。谢谢!事实上,我知道我的用法是错误的,这就是我问如何正确使用的原因。IStream&&是解决方案,如第二个示例所示。谢谢!