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.
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() {}