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

ZoO*_*007 12 c++ parameters auto c++14

我有几个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;
}
Run Code Online (Sandbox Code Playgroud)

我使用eclipse编译gcc 6.1.0和-std = c ++ 14并且它编译但它没有链接.链接器抱怨未定义的引用std::__cxx11::getCollection(someMap);

无论地图数据和我称之为的方式,它总是告诉我:

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

我该如何解决这个问题?

Mr.*_*C64 15

与在C++中一样,auto参数只允许在lambdas中使用(根据@ 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;
}
Run Code Online (Sandbox Code Playgroud)

还要注意添加const一些const -correctness.

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

而且,由于您只对使用字符串流作为输出流感兴趣,因此使用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;
}
Run Code Online (Sandbox Code Playgroud)


Kar*_*oll 7

为什么不使用模板?

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;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 也许提到`auto`不能用作函数的参数类型? (3认同)

Mot*_*tti 6

auto参数只允许在C++ 14 中的lambdas中使用.

可能这是因为在像你这样的经典函数中你可以声明一个函数模板(这基本上是lambda案例中发生的事情),而lambdas不能是模板.