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

标签 c++ c++11 temporary-objects

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

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
现在,我想实现一个函数,它需要一个内存地址或一个 Stream 来读取数据:
// 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
接下来,我想用 Stream 调用 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 传递,因为它是一个内联临时变量,始终被视为右值。
在 PrintMessage 函数返回后,我没有看到临时变量修改自身有任何危害,无论如何它都会被丢弃。
内联 require 我最终想要做的是这样的:
#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)
在这种情况下,右值引用将绑定(bind)到临时对象,并且大部分与左值引用无法区分。

关于c++ - 在 c++ 中传递内联临时类需要是 const。如何解决这个问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64554235/

相关文章:

c++ - 试图编译搅拌库 : error: invalid conversion from ‘const char*’ to ‘char*’

c++ - 可变参数模板 : producing a tuple of pairs of adjacent elements

c++ - vector 中的不可复制元素

c++ - 函数声明而不是在 C++ 中调用构造函数

c++ - 类无法访问其自己的私有(private)静态 constexpr 方法 - Clang 错误?

C++重载

c++ - 如何从文件中读取整数并将每个整数写入不同名称的整数?

c++ - 没有 Boost 的现代 C++ 中的 bimap 实现

c++ - 绑定(bind)到新初始化器中的引用的临时对象的生命周期是多少?

rust - Rust 中涉及临时对象的销毁顺序