简体   繁体   English

C ++ 14在方法定义中使用auto关键字

[英]C++14 using auto keyword in a method's definition

I have several std::unordered_maps . 我有几个std::unordered_maps They all have an std::string as their key and their data differs. 它们都有一个std::string作为键,它们的数据不同。 I want to make a csv string from a given map's keys because that data needs to be sent over the wire to a connected client. 我想从给定地图的密钥创建一个csv字符串,因为该数据需要通过网络发送到连接的客户端。 At the moment I have a method for each individual map. 目前,我为每个地图都有一个方法。 I wanted to make this generic and I came up with the following : 我想让这个通用,我想出了以下内容:

std::string myClass::getCollection(auto& myMap) {
    std::vector <std::string> tmpVec;
    for ( auto& elem : myMap) {
        tmpVec.push_back(elem.first);
    }
    std::stringstream ss;
    for ( auto& elem : tmpVec ) {
        ss << elem <<',';
    }
    std::string result=ss.str();
    result.pop_back(); //remove the last ','
    return result;
}

I compile with gcc 6.1.0 and -std=c++14 using eclipse and it compiles but it doesn't link. 我使用eclipse编译gcc 6.1.0和-std = c ++ 14并且它编译但它没有链接。 The linker complains about undefined reference to std::__cxx11::getCollection(someMap); 链接器抱怨对std::__cxx11::getCollection(someMap);未定义引用std::__cxx11::getCollection(someMap);

Regardless of the map data and the way I call it, it always tells me : 无论地图数据和我称之为的方式,它总是告诉我:

Invalid arguments ' Candidates are: std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>> getCollection() '

How do I solve this? 我该如何解决这个问题?

As in C++14 auto parameters are only allowed in lambdas (as per @ildjarn's comment), you can just develop a function template , templateized on the map type, eg: 与在C ++中一样, auto参数只允许在lambda中使用(根据@ ildjarn的注释),你可以开发一个在地图类型上模板化函数模板 ,例如:

#include <sstream>
#include <string>
#include <vector>

class myClass {
...

template <typename MapType>
std::string getCollection(const MapType& myMap) {
    std::vector <std::string> tmpVec;
    for ( const auto& elem : myMap) {
        tmpVec.push_back(elem.first);
    }
    std::stringstream ss;
    for ( const auto& elem : tmpVec ) {
        ss << elem <<',';
    }
    std::string result=ss.str();
    result.pop_back(); //remove the last ','
    return result;
}

Note also the addition of const for some const -correctness. 还要注意添加const一些常量 -correctness。

Moreover, why not just building the output string directly using the string stream object, without populating an intermediate vector<string> (which is more code, more potential for bugs, more overhead, less efficiency)? 此外,为什么不直接使用字符串流对象构建输出字符串,而不填充中间 vector<string> (这是更多代码,更容易出错,更多开销,效率更低)?

And, since you are just interested in using the string stream as an output stream, using ostringstream instead of stringstream is better as it's more efficient and communicates your intent better. 而且,由于您只对使用字符串流作为输出流感兴趣,因此使用ostringstream而不是stringstream会更好,因为它更有效并且可以更好地传达您的意图。

#include <sstream>  // for std::ostringstream
#include <string>   // for std::string
...

template <typename MapType>
std::string getCollection(const MapType& myMap) {
    std::ostringstream ss;
    for (const auto& elem : myMap) {
        ss << elem.first << ',';
    }
    std::string result = ss.str();
    result.pop_back(); // remove the last ','
    return result;
}

Why not just use a template? 为什么不使用模板?

template <typename TMap>
std::string myClass::GetCollection(TMap &myMap) {
    std::vector <std::string> tmpVec;
    for ( auto& elem : myMap) {
        tmpVec.push_back(elem.first);
    }
    std::stringstream ss;
    for ( auto& elem : tmpVec ) {
        ss << elem <<',';
    }
    std::string result=ss.str();
    result.pop_back(); //remove the last ','
    return result;
}

Your method is exactly the same, but instead of the auto keyword, we use template function syntax to handle the type inference. 您的方法完全相同,但我们使用模板函数语法来处理类型推断,而不是auto关键字。

auto parameters are only allowed in lambdas in C++14. auto参数仅允许在C ++ 14 中的lambdas中使用。

Probably this is since in an classic function like yours you could have declared a function template (which is basically what happens in the lambda case) while lambdas can't be templates. 可能这是因为在像你这样的经典函数中你可以声明一个函数模板(这基本上是lambda案例中发生的事情),而lambdas不能是模板。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM