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;
}
我有几个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;
}