【问题标题】:Error with Auto variable in a function C++函数 C++ 中的 Auto 变量出错
【发布时间】:2020-10-26 08:56:49
【问题描述】:

我在 C++ 中的函数之间传递值时遇到问题。我在下面添加代码。在 mqttReceive 中,接收到 JSON 格式的 MQTT 消息,并在 send() 中再次发送以在 void send() 中接收。但是,我尝试将收到的消息声明为自动,但它不起作用。我错过了什么?

cpp:

void MqttApplication::mqttReceive()
{
    try {
        
        mqttClient->start_consuming();
        mqttClient->subscribe(TOPIC, QOS)->wait();
        
    }
    catch (const mqtt::exception& exc) {
        cerr << exc.what() << endl;
        return;
    }

    
    while (true) {
        auto msg = mqttClient->consume_message();   
        

        try {               
            send(msg);
        }
        catch (const mqtt::exception& exc) {
            cerr << exc.what() << endl;
            return;
        }

        if (msg->get_topic() == "command" &&
                msg->to_string() == "exit") {
            cout << "Exit command received" << endl;
            break;
        }

        cout << msg->get_topic() << ": " << msg->to_string() << endl;
    }
}



void MqttApplication::send(auto msg)
{
    ...
}

hpp:

class MqttApplication : public Application
    {
    private:    
    
        void send(const auto msg);
    
        void mqttReceive();
        

错误:

In file included from /home/mqtt_application.cpp:1:
/home/mqtt_application.hpp:26:24: warning: use of ‘auto’ in parameter declaration only available with ‘-fconcepts-ts’
   26 |     void send(const auto& msg) override;
      |                        ^~~~
/home/mqtt_application.hpp:26:35: error: member template ‘void MqttApplication::send(const auto:1&)’ may not have virt-specifiers
   26 |     void send(const auto& msg) override;
      |                                   ^~~~~~~~
/home/mqtt_application.cpp:320:34: warning: use of ‘auto’ in parameter declaration only available with ‘-fconcepts-ts’
  320 | void MqttApplication::send(auto& msg)
      |                                  ^~~~
/home/mqtt_application.cpp:320:6: error: no declaration matches ‘void MqttApplication::send(auto:2&)’
  320 | void MqttApplication::send(auto& msg)
      |      ^~~~~~~~~~~~~~~~~~
In file included from /home/mqtt_application.cpp:1:
/home/mqtt_application.hpp:26:10: note: candidate is: ‘template<class auto:1> void MqttApplication::send(const auto:1&)’
   26 |     void send(const auto& msg) override;
      |          ^~~~~~~
In file included from /home/mqtt_application.cpp:1:
/home/mqtt_application.hpp:15:7: note: ‘class MqttApplication’ defined here
   15 | class MqttApplication : public Application
      |       ^~~~~~~~~~~~~~~~~~
tools/mqtt.dir/build.make:62: recipe for target 'tools/mqtt.dir/mqtt_application.cpp.o' failed
make[2]: *** [tools/mqtt.dir/mqtt_application.cpp.o] Error 1
CMakeFiles/Makefile2:834: recipe for target 'tools/mqtt.dir/all' failed
make[1]: *** [tools/mqtt.dir/all] Error 2
Makefile:129: recipe for target 'all' failed
make: *** [all] Error 2

我正在使用 C++14 进行编译。我尝试了所有类型的配置,字符串、int 等。输入是一个常规的 JSON 字符串。谢谢

【问题讨论】:

  • 编译器需要知道msg的确切类型。
  • Auto 不是 msg 的正确类型?
  • @thecoder,auto 不是类型。它是一个在特定上下文中工作的占位符,用于告诉编译器推断类型。
  • 试着把 auto 想象成一个别名,在 cpp 文件中,编译器可以从 mqttClient-&gt;consume_message() 推断出返回的类型,所以很高兴调用这个 auto。但是在 hpp 中,当为 ::send(...) 定义函数签名时,编译器无事可做。如果您希望 send 是通用的,您可以考虑模板化 send 否则您需要更具体。

标签: c++ function auto


【解决方案1】:

使用auto 作为参数是C++20 feature,一些编译器在早期版本中支持它作为扩展,但在那里不支持ISO。

【讨论】:

    【解决方案2】:

    函数模板的这种语法需要 C++20。对于 C++17 及更早版本,您需要更改:

    void MqttApplication::send(auto msg)
    

    到:

    template <typename T>
    void MqttApplication::send(T msg)
    

    两者是等价的,但 C++20 版本更短。见Abbreviated function template

    【讨论】:

    • 我可以使用 C++11 声明自动变量,但我不能作为这个版本的参数传递?我的意思是,我只需要将自动消息传递给发送函数。
    • @thecoder 您需要将msg 传递给可以接受msg 类型的函数。 auto 不是一个类型,所以你不能有一个函数接受 auto 作为某种类型的类型。为此,您需要一个函数模板,或者一个接受std::any 的函数。始终牢记 C++ 是一种静态类型语言。所有类型都在编译时扣除。
    【解决方案3】:

    我想知道你预计会发生什么?在函数声明中使用“auto”,编译器无法知道类型是什么,因此它拒绝编译。这与“auto x = 3;”不同,其中编译器知道 x 的类型应该与 3 的类型相同。

    如果您的编译器理解概念并且您理解概念,那么您可以构建您的代码,但这需要您了解一个主要的全新 C++ 功能。

    【讨论】:

    • 这里不涉及任何概念。 void f(auto) 只是一个普通的模板。 void f(Some_Concept auto) 会涉及概念。
    猜你喜欢
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    • 2017-10-20
    • 2012-10-19
    • 2019-01-19
    • 1970-01-01
    相关资源
    最近更新 更多