2016-10-07 35 views
12

我有几个std::unordered_maps。他们都有一个std::string作为他们的关键和他们的数据不同。我想从给定的映射关键字创建一个csv字符串,因为这些数据需要通过线路发送到连接的客户端。目前,我对每个单独的地图都有一个方法。我想使这个通用的,我想出了以下内容:C++ 14在方法的定义中使用auto关键字

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

我用gcc 6.1.0和-std = C++编译14使用Eclipse和它编译,但它不会链接。 链接器抱怨未定义参考std::__cxx11::getCollection(someMap);

无论地图数据的,我把它的方式,它总是告诉我:

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

如何解决这个问题?

+5

'std :: string myClass :: getCollection(auto&myMap)'是无效的语法。具体而言,'auto'不是成员函数的有效参数类型。 – ildjarn

+0

是我试图完成可能使用另一种方法呢?我认为这是可能的使用自动作为参数在C++ 14 ...显然我错了,然后... – ZoOl007

+3

“*我认为有可能使用自动作为参数在C++ 14 ... *“仅限于lambda。 “*是我试图用另一种方法完成的可能性吗?*“是的,只需使用普通模板:'template std :: string myClass :: getCollection(MapT&myMap)' – ildjarn

回答

15

如C++ 14个auto参数lambda表达式只允许(根据@ ildjarn的评论),你可以开发一个函数模板,templateized在地图类型,例如:

#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>(这是更多的代码,对于错误的可能性增加,更多的开销,更少效率)?

而且,由于你是在使用字符串流作为输出流只是感兴趣,使用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; 
} 
+0

感谢您的改进。我一直有相同的链接问题...未定义的参考'std :: __ cxx11 :: – ZoOl007

+0

您是否有模板方法内联实现在某个标头,或者至少可以通过您的客户端代码访问?你是否包含所有必需的标题(例如,'','','',你的地图集合的标题)? –

+0

是的,我有\t模板 \t std :: string getCollection(MapType&myMap);在我的头文件中,该文件包含在模板/函数所在的cpp中,并且也包含在调用类的方法的另一个头文件中 – ZoOl007

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

你的方法是完全一样的,但不是在auto关键字,我们使用模板函数的语法来处理类型推断。

+3

也许提到'auto'不能用作函数的参数类型? – Rakete1111

+0

谢谢。我仍然有相同的undefined引用nce to'std :: __ cxx11 :: – ZoOl007

+0

@ ZoOl007:这是一个命名空间,所以你必须留下一些东西。在这种情况下的重要部分...; - ] – ildjarn

6

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

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

相关问题