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

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

我有几个std::unordered_maps。他们都有一个 std::string 作为他们的关键,他们的数据不同。我想从给定地图的键制作一个 csv 字符串,因为该数据需要通过线路发送到连接的客户端。目前,我对每个单独的地图都有一个方法。我想把它变成通用的,我想出了以下内容:

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;
}

我使用 eclipse 使用 gcc 6.1.0 和 -std=c++14 进行编译,它编译了但没有 link。 linker 抱怨未定义引用 std::__cxx11::getCollection(someMap);

不管地图数据和我怎么称呼它,它总是告诉我:

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

我该如何解决?

为什么不直接使用模板?

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;
}

您的方法完全相同,但我们使用模板函数语法来处理类型推断,而不是 auto 关键字。

auto 参数在 C++14 中是 only allowed in lambdas

可能这是因为在像您这样的经典函数中,您可以声明一个函数模板(这基本上是在 lambda 情况下发生的情况),而 lambda 不能是模板。

因为在 C++14 中 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;
}

另请注意为某些 const-正确性添加 const

此外,为什么不直接使用字符串流对象构建输出字符串,而不填充中间 vector<string>(代码更多,更容易出现错误,更多的开销,更低的效率)?

而且,由于您只对将字符串流用作 output 流感兴趣,因此使用 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;
}