I manage to use Boost MPL vectors and lists just fine, but I just can't figure out maps. When I try to insert into one, I get "too few arguments" from clang 3.1 (gcc 4.7 says something similar). There is a version of insert where the second argument is POS, which is supposed to be ignored, so I tried inserting a dummy type (int) there, but that just gives a new and confusing error.
include <iostream>
#include <boost/mpl/key_type.hpp>
#include <boost/mpl/map.hpp>
using namespace boost;
using namespace mpl;
int main(){
typedef pair<int_<3>, int_<6>> obj;
std::cout << key_type<map<>, obj >::type::value << std::endl; //works
std::cout << has_key<insert<map<>, obj>::type, obj)::type::value << std::endl; //complains on "too few template arguments for class template 'insert'
std::cout << has_key<insert<map<>, int, obj>::type, obj)::type::value << std::endl; // gives "implicit instantiation of undefined template 'boost::mpl::insert<..."
}
MPL errors aren't exactly helpful, even with clang, so I just don't understand what I am doing wrong here? I am sure it is something silly.
http://www.boost.org/doc/libs/1_51_0/libs/mpl/doc/refmanual/map.html
Add
#include <boost/mpl/insert.hpp>
and correct brackets, from ')' to '>'
http://liveworkspace.org/code/afb6632c3eb800412ea551f50c07fb0a
Related
Following https://stackoverflow.com/a/9424211/3368959 I am trying to compare three numbers:
#include <iostream>
int main() {
std::cout << std::min({2,5,1}) << std::endl;
return 0;
}
But the compiler gives me the error:
error: no matching function for call to ‘min(<brace-enclosed initializer list>)’
However, the code compiles just fine when using
std::min(std::min(2,5),1)
But the first way should work with the c++11 standard. What could I be doing wrong?
As #BoBTFish suggested:
In order to use template <class T> T min (initializer_list<T> il) one needs to include <algorithm> as is mentioned here.
I see two ways of accessing a boost::optional variable:
The dereference operator on the variable
The variable itself
If I have this code snippet:
#include <boost/optional.hpp>
#include <iostream>
int main()
{
boost::optional<int> oi;
std::cout << oi << "\n";
}
(where oi is uninitialized) and compile it using "g++-4.9 /tmp/optional.cc" followed by ./a.out, I get 0,
but with this:
#include <boost/optional.hpp>
#include <iostream>
int main()
{
boost::optional<int> oi;
std::cout << *oi << "\n";
}
I get:
a.out: /usr/include/boost/optional/optional.hpp:631: boost::optional<T>::reference_type boost::optional<T>::get() [with T = int; boost::optional<T>::reference_type = int&]: Assertion `this->is_initialized()' failed.
Aborted (core dumped)
which is the expected behavior.
You must have been using an older version of Boost. Your first case triggered a conversion to bool; since the optional does not contain a value, the result of the conversion is false, which is printed as 0.
Newer versions (1.56-1.57) added an operator<< function template declaration to <boost/optional.hpp>
template<class CharType, class CharTrait, class T>
std::basic_ostream<CharType, CharTrait>&
operator<<(std::basic_ostream<CharType, CharTrait>& out, optional<T> const& v);
to catch this kind of mistakes and cause a linker error instead.
Note that including <boost/optional/optional_io.hpp> allows you to actually use the stream operators with optional, in which case optionals that do not contain a value are printed as --.
boost::optional<T> ostream helpers are actually available since boost 1.34. See http://www.boost.org/doc/libs/1_34_0/boost/optional/optional_io.hpp
Note that one needs to EXPLICITLY include <boost/optional/optional_io.hpp> to enable these helpers. It is NOT included by <boost/optional.hpp>.
This is a question regarding the default global namespace in C++. I have the following code that compiles and runs properly using g++ clang-500.2.79.
#include <string>
#include <iostream>
using std::string;
using std::endl;
using std::cout;
bool is_palindrome(const string& str){
return equal(str.begin(), str.end(), str.rbegin());
}
int main(){
cout << "Hello is a palindrome: " << is_palindrome("Hello") << endl;
cout << "madam is a palindrome: " << is_palindrome("madam") << endl;
return 0;
}
My questions is, why does this code compile properly? I forgot to put #include <algorithm> and using std::equal at the beginning of my file. So the expected behaviour is for the compiler to complain.
The example at http://en.cppreference.com/w/cpp/algorithm/equal confirms that I should be using std::equal.
To investigate this further, I tried to track down exactly which version of the equal() function was being called. Being a relative newbie to C++ I don't know exactly how to do this either. I tried,
cout << "The function is: " << equal << endl;
Which generated a compiler error with some interesting information:
/usr/include/c++/4.2.1/bits/stl_algobase.h:771:5:
note: 'std::equal' declared here
Try as I might, I can't find information about stl_algobase (or more probably, I most likely don't understand what I've found). Is stl_algobase a set of functions that are automatically included in the global namespace?
A further questions is: What is the proper way to track (code or otherwise) down which function is being called when you are dealing with potentially overloaded or template functions in C++?
equal is in the std namespace. What you are seeing is argument dependent lookup (ADL). Because the arguments are in the std, the name lookup for equal considers that namespace too.
Here's a simplified example:
namespace foo
{
struct Bar {};
}
namespace foo
{
void bar(const Bar&) {}
void bar(int) {}
}
int main()
{
foo::Bar b;
foo::bar(b); // OK
bar(b); // ADL, OK
foo::bar(42); // OK
bar(42); // No ADL: error: 'bar' was not declared in this scope
}
I have tried to write the following code into my compiler and compile it:
#include <iostream>
#include <bitset>
using namespace std;
void binary(int a)
{
cout << bitset<8>(a).to_string() << endl;
}
int main()
{
binary(16);
system("pause");
return 0;
}
It should give me a binary output but I keep getting an error:
In function `void binary(int)':
no matching function for call to `std::bitset<8u>::to_string()'
I am new to C++ and dont really know what this means, please help me.
I think older versions of bitset::to_string<T>() takes a template argument. So this should work:
cout << bitset<8>(a).to_string<char>() << endl;
bitset don't have a to_string method (stl does not use to_string anyway). You should iterate on values yourself.
I was trying to discover some of the goodies of the new C++11 standard (using g++ 4.6.2). Playing around with lambdas in a an "all_of" algorithm function, I encountered a strange problem with the std:: qualifier.
I am "using" the std namespace as shown at the beginning of the code snippet. This makes the declaration of the pair variable in the for loop well-defined.
However, I tried the same in the lambda argument used in the "all_of" algorithm. I came across several hard-to-understand error messages, before I realized that a full std:: qualified std::pair would work there, but only pair not.
Am I missing an important point? The declaration of the lambda happens in this file, so the namespace should still be active here, right? Or does the required std:: qualifier depend on some STL code in a different file? Or is it likely to be a bug in g++?
Best regards,
Peter
PS: the code compiles without warnings as pasted here, but removing the std:: in the all_of lambda, I get an error message.
#include <iostream>
#include <memory>
#include <map>
#include <string>
#include <algorithm>
#include <utility>
using namespace std;
void duckburg() {
const int threshold = 100;
map <string, int> money;
money["donald"] = 200;
money["daisy"] = 400;
money["scrooge"] = 2000000;
// obviously, an "auto" type would work here nicely,
// but this way my problem is illustrated more clearly:
for (const pair <string, int> &pair : money) {
cout << pair.first << "\t" << pair.second << endl;
}
if (all_of(money.begin(), money.end(),
[&](std::pair<string, int> p) {
return bool(p.second > threshold);
}))
{
cout << "yes, everyone is rich!";
} else {
cout << "no, some are poor!";
};
}
Edit: Just noticed I received a downvote for this old question. No problem with that, but please elaborate on the reasons. It will help me improve future questions, and in the end the entire community will profit. Thanks!
Rename the variable pair in your for loop.
It's scope should only extend to the end of the for loop and therefore not interfere with your
lambda, but g++ has some code for ancient for-scoping rules where that was not the case, so it can emit better error messages for ancient C++ code.
It looks as if there is a bug in that compatibility code.