Link error in Boost program_options code on Ubuntu - c++

I installed boost on ubuntu 10.04 by
sudo apt-get install libboost-dev
I think after that I don't need to set any -I and -L flags, so I compile my code by
g++ test.cpp
Here is my test.cpp
#include <iostream>
#include <string>
#include <set>
#include <sstream>
#include <boost/config.hpp>
#include <boost/program_options/detail/config_file.hpp>
#include <boost/program_options/parsers.hpp>
namespace pod = boost::program_options::detail;
int main()
{
//contents
std::stringstream s(
"a = 1\n"
"b = 2\n"
"c = test option\n");
//parameters
std::set<std::string> options;
options.insert("a");
options.insert("b");
options.insert("c");
//parser
for (pod::config_file_iterator i(s, options), e ; i != e; ++i)
{
std::cout << i->value[0] << std::endl;
}
}
I think things will goes well but actually there are some errors:
/tmp/ccNQEbJM.o: In function `boost::program_options::detail::basic_config_file_iterator<char>::basic_config_file_iterator(std::basic_istream<char, std::char_traits<char> >&, std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, bool)':
a.cpp:(.text._ZN5boost15program_options6detail26basic_config_file_iteratorIcEC1ERSiRKSt3setISsSt4lessISsESaISsEEb[boost::program_options::detail::basic_config_file_iterator<char>::basic_config_file_iterator(std::basic_istream<char, std::char_traits<char> >&, std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, bool)]+0x24): undefined reference to `boost::program_options::detail::common_config_file_iterator::common_config_file_iterator(std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, bool)'
a.cpp:(.text._ZN5boost15program_options6detail26basic_config_file_iteratorIcEC1ERSiRKSt3setISsSt4lessISsESaISsEEb[boost::program_options::detail::basic_config_file_iterator<char>::basic_config_file_iterator(std::basic_istream<char, std::char_traits<char> >&, std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, bool)]+0x5f): undefined reference to `boost::program_options::detail::common_config_file_iterator::get()'
/tmp/ccNQEbJM.o: In function `boost::eof_iterator<boost::program_options::detail::common_config_file_iterator, boost::program_options::basic_option<char> >::increment()':
a.cpp:(.text._ZN5boost12eof_iteratorINS_15program_options6detail27common_config_file_iteratorENS1_12basic_optionIcEEE9incrementEv[boost::eof_iterator<boost::program_options::detail::common_config_file_iterator, boost::program_options::basic_option<char> >::increment()]+0x10): undefined reference to `boost::program_options::detail::common_config_file_iterator::get()'
/tmp/ccNQEbJM.o: In function `boost::program_options::detail::basic_config_file_iterator<char>::getline(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)':
a.cpp:(.text._ZN5boost15program_options6detail26basic_config_file_iteratorIcE7getlineERSs[boost::program_options::detail::basic_config_file_iterator<char>::getline(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)]+0x5b): undefined reference to `boost::program_options::to_internal(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
collect2: ld returned 1 exit status
I can't figure out where and why I went wrong.

You need to link to the Boost program_options library as not everything in Boost is pure templates:
edd#max:/tmp$ cat bpoex.cpp
#include <iostream>
#include <string>
#include <set>
#include <sstream>
#include <boost/config.hpp>
#include <boost/program_options/detail/config_file.hpp>
#include <boost/program_options/parsers.hpp>
namespace pod = boost::program_options::detail;
int main()
{
//contents
std::stringstream s(
"a = 1\n"
"b = 2\n"
"c = test option\n");
//parameters
std::set<std::string> options;
options.insert("a");
options.insert("b");
options.insert("c");
//parser
for (pod::config_file_iterator i(s, options), e ; i != e; ++i)
{
std::cout << i->value[0] << std::endl;
}
}
edd#max:/tmp$ g++ -o bpoex bpoex.cpp -lboost_program_options
edd#max:/tmp$ ./bpoex
1
2
test option
edd#max:/tmp$

Related

OpenABE C++ Library: Undefined Reference Error

I have successfully installed the OpenABE Library - https://github.com/zeutro/openabe
But when I try to compile my own program or run the example - https://github.com/zeutro/openabe/blob/master/examples/test_cp.cpp
g++ test.cpp
I get the Error:
/tmp/ccAcWSoq.o: In function main':
test.cpp:(.text+0x29): undefined reference tooabe::InitializeOpenABE()'
test.cpp:(.text+0x6a): undefined reference to oabe::OpenABECryptoContext::OpenABECryptoContext(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool)'
test.cpp:(.text+0xea): undefined reference tooabe::OpenABECryptoContext::generateParams()'
test.cpp:(.text+0x1bf): undefined reference to oabe::OpenABECryptoContext::keygen(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
test.cpp:(.text+0x27b): undefined reference tooabe::OpenABECryptoContext::encrypt(std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator > const&, std::__cxx11::basic_string, std::allocator >&)'
test.cpp:(.text+0x2dd): undefined reference to oabe::OpenABECryptoContext::decrypt(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)'
test.cpp:(.text+0x385): undefined reference tooabe::ShutdownOpenABE()'
/tmp/ccAcWSoq.o: In function oabe::OpenABECryptoContext::~OpenABECryptoContext()':
test.cpp:(.text._ZN4oabe20OpenABECryptoContextD2Ev[_ZN4oabe20OpenABECryptoContextD5Ev]+0xf): undefined reference tovtable for oabe::OpenABECryptoContext'
collect2: error: ld returned 1 exit status
Here is the code - test.cpp
#include <iostream>
#include <string>
#include <cassert>
#include <openabe/openabe.h>
#include <openabe/zsymcrypto.h>
using namespace std;
using namespace oabe;
using namespace oabe::crypto;
int main(int argc, char **argv){
InitializeOpenABE();
OpenABECryptoContext cpabe("CP-ABE");
string ct, pt1 = "plaintext", pt2;
cpabe.generateParams();
cpabe.keygen("|attr1|attr2","key0");
cpabe.encrypt("attr1 and attr2",pt1,ct);
bool result = cpabe.decrypt("key0",ct,pt2);
assert(result && pt1 == pt2);
cout << "Message: " << pt2 << endl;
ShutdownOpenABE();
return 0;
}
Am I even compiling the file correctly?
Or is there any other issue that I cannot seem to identify?

Error in a function used to find the position of an element in a vector of string (c++)

I have the following function that works fine that I use to find the position of a string in a string vector:
int FindIndexString(vector <string> *Names, string *name)
{
auto it = find(Names->begin(), Names->end(), name->c_str());
if (it == Names->end())
{
error("FindIndexString: %s not found",name->c_str());
}else{
auto index = distance(Names->begin(), it);
return((int)index);
}
}
I need to use this function in a R program that complains about the "auto" specifier and I cannot compile with C++11.
I changed the function to
int FindIndexString(vector <string> *Names, string *name)
{
vector<string>::iterator it;
it = find(Names->begin(), Names->end(), name->c_str());
int pos = (int)distance(Names->begin(), it);
if(it==Names->end())
{
error("FindIndexString: %s not found",name->c_str());;
}else{
return(pos);
}
}
but it doesn't work and I get the following error
In function 'int FindIndexString(std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*, std::string*)':
F_Utils.cpp:92: error: no matching function for call to 'find(__gnu_cxx::__normal_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, __gnu_cxx::__normal_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, const char*)'
Any help?
You need to #include <algorithm> for std::find

RHEL 6.0 Two Similar Pieces of Code: One Compiles One Does Not

Can someone explain why the top piece of code will not compile and the bottom one will?
#include <iterator>
#include <iostream>
#include <set>
#include <string>
#include <fstream>
using namespace std;
int main(int argc, char *argv[])
{
ifstream testFile;
testFile.open("opengl_functions", ios::in);
set<string> myset(istreambuf_iterator<string>(testFile), istreambuf_iterator<string>());
set<string>::iterator it;
for (it = myset.begin(); it != myset.end(); ++it ) {
}
}
//using namespace std;
//
//int main ()
//{
// int myints[] = {75,23,65,42,13};
// set<int> myset (myints,myints+5);
// set<int>::iterator it;
// cout << "myset contains:";
// for ( it=myset.begin() ; it != myset.end(); it++ )
// cout << " " << *it;
// cout << endl;
// return 0;
//}
--
[mehoggan#hogganz400 opengl_parser]$ make
g++ -o parser -Wall ./parser.cpp
./parser.cpp: In function ‘int main(int, char**)’:
./parser.cpp:17: error: request for member ‘begin’ in ‘myset’, which is of non-class type ‘std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(std::istreambuf_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::char_traits<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::istreambuf_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::char_traits<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > (*)())’
./parser.cpp:17: error: request for member ‘end’ in ‘myset’, which is of non-class type ‘std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(std::istreambuf_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::char_traits<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::istreambuf_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::char_traits<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > (*)())’
make: *** [parser] Error 1
Your compiler believes that myset is a function declaration. Look up "the most vexing parse". I always run into it with istream iterators, so I always declare them beforehand. As a side benefit, I find it much easier to read:
std::istreambuf_iterator<string> begin(testFile), end;
std::set<std::string> myset(begin, end);
However, I don't believe that will compile either, but for a different reason. istreambuf_iterator can only be templated on character types. You'll want to use an istream_iterator instead.
std::istream_iterator<string> begin(testFile), end;
std::set<std::string> myset(begin, end);
It is interpreting your declaration of "myset" as a function.
Also: for strings, you need istream_iterator, not istreambuf_iterator:
set<string> myset((istream_iterator<string>(testFile)), (istream_iterator<string>()) );

How to link STL in c++ code?

I wrote some code in source file sql_parse.cc of MySql 5.5.7rc. There I have used vector, allocator, etc but the compiler is not being linked with Standard Template Library(STL). Can anybody suggest me what should I do?
Here is the error msg :
libsql.a(sql_parse.cc.o): In function `std::vector<std::basic_string<char,
std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char,
std::char_traits<char>, std::allocator<char> > > >::push_back(std::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&)':
sql_parse.cc:(.text._ZNSt6vectorISsSaISsEE9push_backERKSs[std::vector<std::basic_string<char,
std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char,
std::char_traits<char>, std::allocator<char> > > >::push_back(std::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&)]+0x74): undefined reference to
`std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >
>::_M_insert_aux(__gnu_cxx::__normal_iterator<std::basic_string<char,
std::char_traits<char>, std::allocator<char> >*, std::vector<std::basic_string<char,
std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char,
std::char_traits<char>, std::allocator<char> > > > >, std::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&)'
collect2: ld returned 1 exit status
You should've given the command line. I suspect that you use gcc for linking in which case you should either use g++ or add -lstdc++ option.
I got my stl code to compile with the following
g++ -std=c++11 file.cpp -o prog
undefined reference to
std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >
::_M_insert_aux(__gnu_cxx::__normal_iterator<std::basic_string<char,
std::char_traits<char>, std::allocator<char> >*, std::vector<std::basic_string<char,
std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char,
std::char_traits<char>, std::allocator<char> > > > >, std::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&)'
That symbol is a member function of std::vector<std::string> and is a function template, so should be instantiated in your program, not in the C++ standard library.
Are you compiling with the -fno-implicit-templates option? Or using an explicit instantiation declaration (i.e. extern template) in your code and not providing the definition? Those would prevent the compiler from instantiation the template.
If you're telling the compiler not to provide implicit instantiations then you will need to add an explicit instantiation for each undefined reference:
template void std::vector<std::string>::_M_insert_aux(std::vector<std::string>::iterator, std::string const&);
#ifndef GLOBAL_H
#define GLOBAL_H
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
#endif //GLOBAL_H
Is a good start

linker error when using tr1::regex

I've got a program that uses tr1::regex, and while it compiles, it gives me very verbose linker errors.
Here's my header file MapObject.hpp:
#include <iostream>
#include <string>
#include <tr1/regex>
#include "phBaseObject.hpp"
using std::string;
namespace phObject
{
class MapObject: public phBaseObject
{
private:
string color; // must be a hex string represented as "#XXXXXX"
static const std::tr1::regex colorRX; // enforces the rule above
public:
void setColor(const string&);
(...)
};
}
Here's my implementation:
#include <iostream>
#include <string>
#include <tr1/regex>
#include "MapObject.hpp"
using namespace std;
namespace phObject
{
const tr1::regex MapObject::colorRX("#[a-fA-F0-9]{6}");
void MapObject::setColor(const string& c)
{
if(tr1::regex_match(c.begin(), c.end(), colorRX))
{
color = c;
}
else cerr << "Invalid color assignment (" << c << ")" << endl;
}
(...)
}
and now for the errors:
max#max-desktop:~/Desktop/Development/CppPartyHack/PartyHack/lib$ g++ -Wall -std=c++0x MapObject.cpp
/tmp/cce5gojG.o: In function std::tr1::basic_regex<char, std::tr1::regex_traits<char> >::basic_regex(char const*, unsigned int)':
MapObject.cpp:(.text._ZNSt3tr111basic_regexIcNS_12regex_traitsIcEEEC1EPKcj[std::tr1::basic_regex<char, std::tr1::regex_traits<char> >::basic_regex(char const*, unsigned int)]+0x61): undefined reference tostd::tr1::basic_regex >::_M_compile()'
/tmp/cce5gojG.o: In function bool std::tr1::regex_match<__gnu_cxx::__normal_iterator<char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, char, std::tr1::regex_traits<char> >(__gnu_cxx::__normal_iterator<char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::basic_regex<char, std::tr1::regex_traits<char> > const&, std::bitset<11u>)':
MapObject.cpp:(.text._ZNSt3tr111regex_matchIN9__gnu_cxx17__normal_iteratorIPKcSsEEcNS_12regex_traitsIcEEEEbT_S8_RKNS_11basic_regexIT0_T1_EESt6bitsetILj11EE[bool std::tr1::regex_match<__gnu_cxx::__normal_iterator<char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, char, std::tr1::regex_traits<char> >(__gnu_cxx::__normal_iterator<char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::basic_regex<char, std::tr1::regex_traits<char> > const&, std::bitset<11u>)]+0x53): undefined reference tobool std::tr1::regex_match<__gnu_cxx::__normal_iterator, std::allocator > >, std::allocator, std::allocator > > > >, char, std::tr1::regex_traits >(__gnu_cxx::__normal_iterator, std::allocator > >, __gnu_cxx::__normal_iterator, std::allocator > >, std::tr1::match_results<__gnu_cxx::__normal_iterator, std::allocator > >, std::allocator, std::allocator > > > > >&, std::tr1::basic_regex > const&, std::bitset<11u>)'
collect2: ld returned 1 exit status
I can't really make heads or tails of this, except for the undefined reference to std::tr1::basic_regex near the beginning. Anyone know what's going on?
Regex support for C++0x is incomplete and wasn't there for TR1, see the implementation status page for C++0x/TR1.
Boost offers an alternative TR1 implementation as well as the original library it is based on.
The answer is, even though the header is supplied, some of the methods are not supplied.
One could deduce this from Georg's answer, but after thinking up and coding a hundred lines or so based on the assumption that the nifty library was actually provided, one might be too tired for any further deductions.