Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have several std::unordered_maps. They all have an std::string as their key and their data differs. 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. 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. The linker complains about undefined reference to 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?

like image 864
ZoOl007 Avatar asked Oct 07 '16 10:10

ZoOl007


People also ask

What is the use of auto keyword in C++?

The auto keyword is a simple way to declare a variable that has a complicated type. For example, you can use auto to declare a variable where the initialization expression involves templates, pointers to functions, or pointers to members.

Is it good to use auto in C++?

Good use of auto is to avoid long initializations when creating iterators for containers. Note: The variable declared with auto keyword should be initialized at the time of its declaration only or else there will be a compile-time error.

What does Auto& mean?

It means that loop will parse each element inside threads vector. Inside the for, you need to specify the alias auto& in order to avoid creating a copy of the elements inside the vector within the thread variable.

What is the use of auto keyword in C++?

The auto keyword specifies the type of the variable that is being declared will be automatically identified by the compiler. NOTE : If a function will return an auto type then it will evaluted during run time. NOTE : The typeid operator allows the type of an object to be determined at run time.

What is auto in C with example?

C auto – meaning, usage, examples in code. In the language C auto is a keyword for specifying a storage duration. When you create an auto variable it has an “automatic storage duration”. We call these objects “local variables”. In C, all variables in functions are local by default.

Can we use Auto for a function type in C++14?

In C++14 we can use auto for a function type. The above code can be further simplified to: The C++14 code is shorter, easier to read and more general than the C++11 version. Here is complete code:

What is the default auto keyword for local variables?

As auto keyword is the local lifetime is the default for local variables, auto keyword is extremely rarely used it’s only meaningful to a compiler-writer or interpreter developer making an entry in a symbol table or better readability auto keyword can be used.


Video Answer


1 Answers

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, e.g.:

#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.

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)?

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.

#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;
}
like image 67
Mr.C64 Avatar answered Oct 27 '22 04:10

Mr.C64