HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Reading strings into a vector, without using namespace std

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
stdreadingwithoutnamespaceintousingstringsvector

Problem

I have been told that using namespace std is a bad practice (especially in header files). But wouldn't this make the program less readable?

int main()
{
    std::string text;
    std::vector svec;

    while(std::cin >> text)
        svec.push_back(text);

    for(std::vector::size_type i = 0; i < svec.size(); i++)
        std::cout << svec[i]  + " " << svec[i].size() << "\n";

    return 0;
}


Does this not make the for loop difficult to read, even for a simple program as this? Is there a better way to do this?

Solution

I'll assume that you've read Why is using namespace std considered bad practice? so you understand the reasons that this can cause problems for your code. I'm not going to address that any further in this answer.

You have alternatives, that reduce the risk compared to using namespace std; at file scope:

-
Selectively import names you're going to use, in the scope you're going to use them:

#include 
#include 
#include 

int main()
{
    using std::string;
    using std::vector;

    string text;
    vector svec;

    while (std::cin >> text)
        svec.push_back(text);

    for (vector::size_type i = 0; i < svec.size(); i++)
        std::cout << svec[i]  + " " << svec[i].size() << "\n";

    return 0;
}


This is an important technique when using free functions such as begin() and end() in generic code, where you want the std:: implementations to be available, but for argument-dependent lookup to prefer a more specific (local namespace) override if available.

-
Reduce the need to actually write typenames, with greater use of auto. For example, your output loop can be

for (const auto& element: svec)
    std::cout << element << " " << element.size() << "\n";


Using auto more liberally can be very helpful when you decide that a method needs to be generic; you won't need to trawl through it updating the types to match the new signature.

As an aside, note that some namespaces (e.g. std::literals and its contained namespaces) are intended to be imported with a using namespace directive; you may still want to restrict their scope to just that part of your code that needs it, though - and never in a header file!

Code Snippets

#include <string>
#include <vector>
#include <iostream>

int main()
{
    using std::string;
    using std::vector;

    string text;
    vector<string> svec;

    while (std::cin >> text)
        svec.push_back(text);

    for (vector<string>::size_type i = 0; i < svec.size(); i++)
        std::cout << svec[i]  + " " << svec[i].size() << "\n";

    return 0;
}
for (const auto& element: svec)
    std::cout << element << " " << element.size() << "\n";

Context

StackExchange Code Review Q#157228, answer score: 8

Revisions (0)

No revisions yet.