Using boost::program_options with enum in class in namespace
Asked Answered
K

1

8

I'm using boost::program_options to parse the command line for my program and am having trouble trying to read a value into a public enum in a class which is also in a namespace.

Specifics:

Boost 1.44.0
g++ 4.4.7

I tried following the process spelled out in Boost Custom Validator for Enum but it isn't working for me.

Parameters.h

#include <istream>

namespace SA
{
    class Parameters
    {
    public:
        enum Algorithm
        {
            ALGORITHM_1,
            ALGORITHM_2,
            ALGORITHM_3,
            ALGORITHM_4
        };

        friend istream& operator>> (istream &in, Parameters::Algorithm &algorithm);

        Algorithm mAlgorithm;

        <More Parameters>
     }
}

Parmaeters.cpp

#include <boost/algorithm/string.hpp>

using namespace SA;

istream& operator>> (istream &in, Parameters::Algorithm &algorithm)
{
    string token;
    in >> token;

    boost::to_upper (token);

    if (token == "ALGORITHM_1")
    {
        algorithm = ALGORITHM_1;
    }
    else if (token == "ALGORITHM_2")
    {
        algorithm = ALGORITHM_2;
    }
    else if (token == "ALGORITHM_3")
    {
        algorithm = ALGORITHM_3;
    }
    else if (token == "ALGORITHM_4")
    {
        algorithm = ALGORITHM_4;
    }
    else
    {
        throw boost::program_options::validation_error ("Invalid Algorithm");
    }

    return in;
}

main.cpp

#include <boost/program_options.hpp>

using namespace SA;

int main (int argc, char **argv)
{
    po::options_description options ("Test: [options] <data file>\n    Where options are:");
    options.add_options ()
        ("algorithm", po::value<Parameters::Algorithm>(&Parameters::mAlgorithm)->default_value (Parameters::ALGORITHM_3), "Algorithm");
    <More options>

    <...>
}

When I compile, I get the following error:

main.o: In function 'bool boost::detail::lexical_stream_limited_src<char, std::basic_streambuf<char, std::char_traits<char> >, std::char_traits<char> >::operator>><SA::Parameters::Algorithm>(SA::Parameters::Algorithm&)':
/usr/include/boost/lexical_cast.hpp:785: undefined reference to 'SA::operator>>(std::basic_istream<car, std:char_traits<char> >&, SA::Parameters::Algorithm&)'

I tried putting the operator>> in main and got the same error.

I've spent a couple of days on this now and am not where to go from here. If anyone has any ideas, it would be greatly appreciated.

Karolinekaroly answered 19/6, 2014 at 15:12 Comment(1)
Try to define your operator>> inside namespace SA.Voluminous
V
3

With your friend declaration, you declare

namespace SA {
    istream& operator>> (istream &in, Parameters::Algorithm &algorithm);
}

And your implement in global namespace:

istream& operator>> (istream &in, Parameters::Algorithm &algorithm);

Move your implementation inside namespace SA.

For you information:

namespace SA { void foo(); }

using namespace SA;

void foo() {} // implement ::foo and not SA::foo()

You have to use

namespace SA { void foo() {} }

or

void SA::foo() {}
Voluminous answered 19/6, 2014 at 15:18 Comment(3)
Unfortunately, the computer I have the code on is not on the Internet, so I had to type this in on a different computer and forgot to put in that I had a using namespace SA. I have edited my original post to reflect that it was there all along.Karolinekaroly
My answer is still valid. I have done edit to highlight some points.Voluminous
Okay. I didn't realize they were different. It now works! Thank you!Karolinekaroly

© 2022 - 2024 — McMap. All rights reserved.