I have a Map std::map<std::string, boost::any>, which comes from the boost::program_options package. Now I would like to print the content of that map:
for(po::variables_map::const_iterator it = vm.begin(); it != vm.end(); ++it) {
std::cerr << it->first << ": " << it->second << std::endl;
}
Unfortunately, that is not possible because boost::any doesn't have an operator<< defined.
What is the easiest way to print that map?
I could define my own output operator for any that automatically tries to cast each any to an int, then double, then string, etc., each time ignoring errors and trying to cast until the cast is successful and I can print as the specified type.
But there should be an easier method in Boost? I'd need something like a reverse lexical_cast...
You could use boost::spirit::hold_any instead. It's defined here:
#include <boost/spirit/home/support/detail/hold_any.hpp>
and is fully compatible with boost::any. This class has two differences if compared to boost::any:
it utilizes the small object optimization idiom and a couple of other optimization tricks, making spirit::hold_any smaller and faster than boost::any
it has the streaming operators (operator<<() and operator>>()) defined, allowing to input and output a spirit::hold_any seemlessly.
The only limitation is that you can't input into an empty spirit::hold_any, but it needs to be holding a (possibly default constructed) instance of the type which is expected from the input.
If you can change boost::any to another type, you can use Boost.TypeErasure. If you ever wanted to create a type that's like any, but only supporting types that support these particular operations at compile time, then this is just for you.
#include <boost/type_erasure/operators.hpp>
#include <boost/type_erasure/any.hpp>
#include <boost/mpl/vector.hpp>
#include <random>
#include <iostream>
namespace te = boost::type_erasure;
typedef te::any<boost::mpl::vector<
te::copy_constructible<>,
te::destructible<>,
te::ostreamable<>
>> streamable_any;
int main()
{
streamable_any i(42);
streamable_any d(23.5);
std::mt19937 mt;
streamable_any r(mt);
std::cout << i << "\n" << d << "\n" << r << "\n";
}
Live On Coliru
Unfortunately, with any the only way is to use the type() method to determine what is contained within any, then cast it with any_cast. Obviously you must have RTTI enabled, but you probably already do if you're using any:
for(po::variables_map::const_iterator it = vm.begin(); it != vm.end(); ++it) {
if(typeid(float) == it->second.type()) {
std::cerr << it->first << ": " << any_cast<float>(it->second) << std::endl;
}
else if(typeid(int) == it->second.type()) {
std::cerr << it->first << ": " << any_cast<int>(it->second) << std::endl;
}
...
}
Define some aux function to output to stream:
template<class T>
bool out_to_stream(std::ostream& os, const boost::any& any_value)
{
try {
T v = boost::any_cast<T>(any_value);
os << v;
return true;
} catch(boost:: bad_any_cast& e) {
return false;
}
}
You can define a special formatting for some types
template<>
bool out_to_stream<std::string>(std::ostream& os, const boost::any& any_value)
{
try {
std::string v(std::move(boost::any_cast<std::string>(any_value)));
os << "'" << v << "'";
return true;
} catch(boost:: bad_any_cast& e) {
return false;
}
}
or
template<>
bool out_to_stream<bool>(std::ostream& os, const boost::any& any_value)
{
try {
os << ((boost::any_cast<bool>(any_value))? "yes" : "no");
return true;
} catch(boost:: bad_any_cast& e) {
return false;
}
}
Then define an output operator for boost::any where you list all types you want to try to cast and output
std::ostream& operator<<(std::ostream& os, const boost::any& any_value)
{
//list all types you want to try
if(!out_to_stream<int>(os, any_value))
if(!out_to_stream<double>(os, any_value))
if(!out_to_stream<bool>(os, any_value))
if(!out_to_stream<std::string>(os, any_value))
os<<"{unknown}"; // all cast are failed, an unknown type of any
return os;
}
And then for a value_type:
std::ostream& operator<<(std::ostream& os, const boost::program_options::variable_value& cmdline_val)
{
if(cmdline_val.empty()){
os << "<empty>";
} else {
os<<cmdline_val.value();
if(cmdline_val.defaulted())
os << "(default)";
}
return os;
}
The list of type switches proposed in other answers can be improved with a loop over a type list using Boost MPL (see documentation of mpl::for_each and mpl::vector). The following code defines an operator<< for any boost::any that is given in the type list SupportedTypes and throws an exception otherwise.
#include <stdexcept>
#include <iostream>
#include <string>
#include <cstdint>
#include <boost/any.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/vector.hpp>
class StreamInserter
{
private:
std::ostream& os_;
const boost::any &v_;
mutable bool has_printed_;
public:
struct UnsupportedType {};
StreamInserter(std::ostream& os, const boost::any &v)
: os_(os), v_(v), has_printed_(false) {}
template <typename T>
void operator()(const T&) const
{
if (!has_printed_ && v_.type() == typeid(T))
{
os_ << boost::any_cast<T>(v_);
has_printed_ = true;
}
}
void operator()(const UnsupportedType&) const
{
if (!has_printed_)
throw std::runtime_error("unsupported type");
}
};
std::ostream& operator<<(std::ostream& os, const boost::any& v)
{
typedef boost::mpl::vector<float, double, int8_t, uint8_t, int16_t, uint16_t,
int32_t, uint32_t, int64_t, uint64_t, std::string, const char*,
StreamInserter::UnsupportedType> SupportedTypes;
StreamInserter si(os, v);
boost::mpl::for_each<SupportedTypes>(si);
return os;
}
int main(int, char**)
{
std::cout << boost::any(42.0) << std::endl;
std::cout << boost::any(42) << std::endl;
std::cout << boost::any(42UL) << std::endl;
std::cout << boost::any("42") << std::endl;
std::cout << boost::any(std::string("42")) << std::endl;
std::cout << boost::any(bool(42)) << std::endl; // throws exception
}
I think you have to cover each possible case of objects you have to print... Or use boost::variant.
EDIT: Sorry, I thought I shall write WHY.
The reason why I think that is because, looking at any source code, it seems to rely on the fact that YOU provide the types when inserting and getting data. When you insert, data is automatically detected by the compiler, so you don't have to specify it. But when you get the data, you shall use any_cast, because you're not sure of the data type you're getting.
If it worked in a different way and data type was sure, I think that would be no need for any_cast :)
Instead, variant have a limited set of possible data types, and this information is somewhat registered, giving you the ability to iterate in a generic way a variant container.
If you need this kind of manipulation - iterating a generic set of values - I think you shall use variant.
Try using xany https://sourceforge.net/projects/extendableany/?source=directory xany class allows to add new methods to any's existing functionality. By the way there is a example in documentation which does exactly what you want.
Rather than re-writing my class to use boost::spirit::hold_any, I created a way to stream boost::any, similar to what manifest suggested, but just in one place.
ostream& operator<<(ostream& _os, const boost::any& _any)
{
// only define simple type conversions
if (_any.type() == typeid(int))
_os << boost::any_cast<int>(_any);
/*any other types you use...*/
}
Rather cumbersome, but it allows me to stream a boost::any variable anywhere in my code.
How about being able to construct a boost::spirit::hold_any from a boost:any?
A little late for this party, but anyone that may be interested can also use std::tuple and a std::for_each-like template that iterates over a tuple.
This is based on the answer from ingomueller.net in this thread.
I had a recent case where I created a property map (reading configuration values, mainly fundamental types, from an XML file and inserting them into an std::unordered_map, where the value type is of type any. For debugging purposes I wanted to be able to print the entire map with its keys and values along with the type of the value.
In that project I am not using Boost at all, I used my own any implementation, but its very similar to boost::any.
The insertion operator basically looks like this:
template <typename TChar>
inline std::basic_ostream<TChar>&
operator<< (std::basic_ostream<TChar>& os, const sl::common::any& v)
{
// Types that we support with sl::common::any.
std::tuple<
float, double, bool,
int8_t, uint8_t,
int16_t, uint16_t,
int32_t, uint32_t,
int64_t, uint64_t,
std::wstring, const wchar_t*,
StreamInserter::UnsupportedType> t;
// Prepare ostream for printing a value of type any
StreamInserter si(os, v);
// Iterate over all types in tuple t. If the last type(UnsupportedType) is
// reached, given v is unsupported.
for_each(t, si);
return os;
}
The for_each template looks like this (C++14):
template <typename Tuple, typename F, std::size_t ...Indices>
constexpr void for_each_impl(Tuple&& tuple, F&& f, std::index_sequence<Indices...>) {
using swallow = int[];
(void)swallow{1,
(f(std::get<Indices>(std::forward<Tuple>(tuple))), void(), int{})...
};
}
template <typename Tuple, typename F>
constexpr void for_each(Tuple&& tuple, F&& f) {
constexpr std::size_t N = std::tuple_size<std::remove_reference_t<Tuple>>::value;
for_each_impl(std::forward<Tuple>(tuple), std::forward<F>(f),
std::make_index_sequence<N>{});
}
With this just use the StreamInserter class or something similar shown in Ingos answer.
Hope this helps.
Related
I wonder, why functional objects in c++ are implemented as templated, with void as default type since c++14.
For example:
https://en.cppreference.com/w/cpp/utility/functional/plus
https://en.cppreference.com/w/cpp/utility/functional/minus
This object in fact performs arithmetic operation +, -, *, /, when called by operator().
The operator() has to be template to work with different types as arguments, but why does the struct have to be?
EDIT
I can create an operator std::plus<>, which may work with a different types in operator():
struct Foo{
int foo;
};
Foo operator+(const Foo& lhs, const Foo& rhs){
return {2 * lhs.foo + 3 * rhs.foo};
}
std::ostream& operator<<(std::ostream& os, const Foo& f){
std::cout << f.foo;
return os;
}
int main()
{
auto op = std::plus<>();
std::cout << op(5, 3) << "\n";
std::cout << op(3.14, 2.71) << "\n";
std::cout << op(Foo(2), Foo(3)) << "\n";
}
And this gives the expected output. Or it may be the case, that having specified the type initially you get something more optimized?
It's a design choice. If you specify the type there is no template operator(), instead the whole class is a template. The operator() is simply something like
constexpr T operator()(const T &lhs, const T &rhs) const
{
return lhs + rhs;
}
This is in several ways different from having a template operator().
If we pass a std::plus<int> it's a plus functor for specifically ints and nothing else.
If we instead passed a std::plus<> without specifying the type it would have a templated operator(). That functor could apply it's operator() to any valid type.
Some advantages with restricting the type from the top of my head:
Since the type is specified the functor can deal with implicit conversion without any issues.
You know for a fact that the functor is not going to silently do things we don't want it to. It's only ever going to do addition on Ts.
Edit
Some examples when the behaviour would differ.
#include <iostream>
#include <functional>
#include <string>
struct Foo {};
int main()
{
auto stringadd = std::plus<std::string>{};
auto anyadd = std::plus<>{};
std::cout << stringadd("hey ", "you") << '\n';
//std::cout << anyadd("hey ", "you") << '\n'; // error: no match for call to '(std::plus<void>) (const char [5], const char [4])'
//std::cout << stringadd("hey ", 1) << '\n'; // error: no match for call to '(std::plus<std::__cxx11::basic_string<char> >) (const char [5], int)'
std::cout << anyadd("hey ", 1) << '\n';
}
I have a "dictionary" std::map<std::string, boost::any> (or std::any, if you want) that can possibly be nested. Now, I would like to display the map. Since boost::any obviously doesn't play nicely with <<, things are getting a little nasty. So far, I'm checking the type, cast it, and pipe the cast to cout:
for (const auto &p: map) {
std::cout << std::string(indent + 2, ' ') << p.first << ": ";
if (p.second.type() == typeid(int)) {
std::cout << boost::any_cast<int>(p.second);
} else if (p.second.type() == typeid(double)) {
std::cout << boost::any_cast<double>(p.second);
} else if (p.second.type() == typeid(std::string)) {
std::cout << boost::any_cast<std::string>(p.second);
} else if (p.second.type() == typeid(const char*)) {
std::cout << boost::any_cast<const char*>(p.second);
} else if (p.second.type() == typeid(std::map<std::string, boost::any>)) {
show_map(
boost::any_cast<std::map<std::string, boost::any>>(p.second),
indent + 2
);
} else {
std::cout << "[unhandled type]";
}
std::cout << std::endl;
}
std::cout << std::string(indent, ' ') << "}";
This prints, for example
{
fruit: banana
taste: {
sweet: 1.0
bitter: 0.1
}
}
Unfortunately, this is hardly scalable. I'd have to add another else if clause for every type (e.g., float, size_t,...), which is why I'm not particularly happy with the solution.
Is there a way to generalize the above to more types?
One thing you can do to lessen (but not remove) the pain is to factor the type determination logic into one support function, while using static polymorphism (specifically templates) for the action to be applied to the values...
#include <iostream>
#include <boost/any.hpp>
#include <string>
struct Printer
{
std::ostream& os_;
template <typename T>
void operator()(const T& t)
{
os_ << t;
}
};
template <typename F>
void f_any(F& f, const boost::any& a)
{
if (auto p = boost::any_cast<std::string>(&a)) f(*p);
if (auto p = boost::any_cast<double>(&a)) f(*p);
if (auto p = boost::any_cast<int>(&a)) f(*p);
// whatever handling for unknown types...
}
int main()
{
boost::any anys[] = { std::string("hi"), 3.14159, 27 };
Printer printer{std::cout};
for (const auto& a : anys)
{
f_any(printer, a);
std::cout << '\n';
}
}
(With only a smidge more effort, you could have the type-specific test and dispatch done for each type in a variadic template parameter pack, simplifying that code and the hassle of maintaining the list. Or, you could just use a preprocessor macro to churn out the if-cast/dispatch statements....)
Still - if you know the set of types, a boost::variant is more appropriate and already supports similar operations (see here).
Yet another option is to "memorise" how to do specific operations - such as printing - when you create your types:
#include <iostream>
#include <boost/any.hpp>
#include <string>
#include <functional>
struct Super_Any : boost::any
{
template <typename T>
Super_Any(const T& t)
: boost::any(t),
printer_([](std::ostream& os, const boost::any& a) { os << boost::any_cast<const T&>(a); })
{ }
std::function<void(std::ostream&, const boost::any&)> printer_;
};
int main()
{
Super_Any anys[] = { std::string("hi"), 3.14159, 27 };
for (const auto& a : anys)
{
a.printer_(std::cout, a);
std::cout << '\n';
}
}
If you have many operations and want to reduce memory usage, you can have the templated constructor create and store a (abstract-base-class) pointer to a static-type-specific class deriving from an abstract interface with the operations you want to support: that way you're only adding one pointer per Super_Any object.
Since you're already using Boost you could consider boost::spirit::hold_any.
It already has pre-defined streaming operators (both operator<<() and operator>>()).
Just the embedded type must have the corresponding operator defined, but in your use context this seems to be completely safe.
Despite being in the detail namespace, hold_any is quite widespread and almost a ready-to-use boost:any substitute (e.g. Type Erasure - Part IV, Why you shouldn’t use boost::any)
A recent version of Boost is required (old versions had a broken copy assignment operator).
I have a "dictionary" std::map<std::string, boost::any> (or std::any, if you want) that can possibly be nested. Now, I would like to display the map. Since boost::any obviously doesn't play nicely with <<, things are getting a little nasty. So far, I'm checking the type, cast it, and pipe the cast to cout:
for (const auto &p: map) {
std::cout << std::string(indent + 2, ' ') << p.first << ": ";
if (p.second.type() == typeid(int)) {
std::cout << boost::any_cast<int>(p.second);
} else if (p.second.type() == typeid(double)) {
std::cout << boost::any_cast<double>(p.second);
} else if (p.second.type() == typeid(std::string)) {
std::cout << boost::any_cast<std::string>(p.second);
} else if (p.second.type() == typeid(const char*)) {
std::cout << boost::any_cast<const char*>(p.second);
} else if (p.second.type() == typeid(std::map<std::string, boost::any>)) {
show_map(
boost::any_cast<std::map<std::string, boost::any>>(p.second),
indent + 2
);
} else {
std::cout << "[unhandled type]";
}
std::cout << std::endl;
}
std::cout << std::string(indent, ' ') << "}";
This prints, for example
{
fruit: banana
taste: {
sweet: 1.0
bitter: 0.1
}
}
Unfortunately, this is hardly scalable. I'd have to add another else if clause for every type (e.g., float, size_t,...), which is why I'm not particularly happy with the solution.
Is there a way to generalize the above to more types?
One thing you can do to lessen (but not remove) the pain is to factor the type determination logic into one support function, while using static polymorphism (specifically templates) for the action to be applied to the values...
#include <iostream>
#include <boost/any.hpp>
#include <string>
struct Printer
{
std::ostream& os_;
template <typename T>
void operator()(const T& t)
{
os_ << t;
}
};
template <typename F>
void f_any(F& f, const boost::any& a)
{
if (auto p = boost::any_cast<std::string>(&a)) f(*p);
if (auto p = boost::any_cast<double>(&a)) f(*p);
if (auto p = boost::any_cast<int>(&a)) f(*p);
// whatever handling for unknown types...
}
int main()
{
boost::any anys[] = { std::string("hi"), 3.14159, 27 };
Printer printer{std::cout};
for (const auto& a : anys)
{
f_any(printer, a);
std::cout << '\n';
}
}
(With only a smidge more effort, you could have the type-specific test and dispatch done for each type in a variadic template parameter pack, simplifying that code and the hassle of maintaining the list. Or, you could just use a preprocessor macro to churn out the if-cast/dispatch statements....)
Still - if you know the set of types, a boost::variant is more appropriate and already supports similar operations (see here).
Yet another option is to "memorise" how to do specific operations - such as printing - when you create your types:
#include <iostream>
#include <boost/any.hpp>
#include <string>
#include <functional>
struct Super_Any : boost::any
{
template <typename T>
Super_Any(const T& t)
: boost::any(t),
printer_([](std::ostream& os, const boost::any& a) { os << boost::any_cast<const T&>(a); })
{ }
std::function<void(std::ostream&, const boost::any&)> printer_;
};
int main()
{
Super_Any anys[] = { std::string("hi"), 3.14159, 27 };
for (const auto& a : anys)
{
a.printer_(std::cout, a);
std::cout << '\n';
}
}
If you have many operations and want to reduce memory usage, you can have the templated constructor create and store a (abstract-base-class) pointer to a static-type-specific class deriving from an abstract interface with the operations you want to support: that way you're only adding one pointer per Super_Any object.
Since you're already using Boost you could consider boost::spirit::hold_any.
It already has pre-defined streaming operators (both operator<<() and operator>>()).
Just the embedded type must have the corresponding operator defined, but in your use context this seems to be completely safe.
Despite being in the detail namespace, hold_any is quite widespread and almost a ready-to-use boost:any substitute (e.g. Type Erasure - Part IV, Why you shouldn’t use boost::any)
A recent version of Boost is required (old versions had a broken copy assignment operator).
I wish I could just print contents of a set/vector/map by using cout << . It doesn't seem so difficult for the stl designers to implement : Assuming that << is defined for T, << for a container could just iterate through the elements and print them using ofstream << .
Is there an easy way to print them that I dont know of?
If not, Is there an easy solution? I have read at places that extending stl classes is a bad idea. Is that so, and why?
how about defining an something like an overloaded print function?
EDIT:
I am looking for a recursive function which can handle containers of containers of ...
I agree that different people would like different formats, but something overridable is better than nothing
Probably the easiest way to output an STL container is
std::copy(cont.begin(), cont.end(),
std::ostream_iterator<Type>(std::cout, " "));
where Type is the type of the elements of cont (e.g. if cont is of type std::vector<int> then Type must be int).
Of course instead of std::cout you can use any ostream.
In C++11 you can use range-based for:
for (auto& i: container) cout << i << " ";
cout << endl;
The easiest eay to dump a container is probably just using std::copy(). For example I typically use something like this:
template <typename C>
std::string format(C const& c) {
std::ostringstream out;
out << "[";
if (!c.empty()) {
std::copy(c.begin(), --c.end(),
std::ostream_iterator<typename C::value_type>(out, ", "));
out << c.back();
}
out << "]";
return out.str();
}
Yes, this doesn't always work but works for my needs. This actually shows one of the problems why there is no output for containers in the standard library: there are many different ways how containers can be formatted. To make matters worse, the formatted output should be readable where thing become real fun. All of this is doable but I'm not aware of a corresponding proposal.
It doesn't seem so difficult for the stl designers to implement : Assuming that << is defined for T, << for a container could just iterate through the elements and print them using ofstream << .
Of course it is not hard for them. However, ask yourself: Does the format of the output make sense for every client? The standard library is about reuse and genericity. Coupling containers with some arbitrary output formatting rules makes them less generic for the sake of only some.
The recommended solution therefore is to provide your own operator<<(std::ostream &, T) and/or to take other generic algorithms, as found in e.g. <algorithms>.
Are you looking something like this?
#include <iostream>
#include <set>
template <typename T>
std::ostream& operator<< (std::ostream& os, const std::set<T>& s)
{
for( auto i: s ) {
os << i << " ";
}
return os;
}
Then you just may use it this way:
std::set<int> my_set = { 11, 12, 13 };
std::cout << my_set << std::endl;
Using Template template parameter makes it easy, in order to make it working for each collection you need both template<class, class...> class X and class... Args as template parameters:
template<class T, template<class, class...> class X, class... Args>
std::ostream& operator <<(std::ostream& os, const X<T, Args...>& objs) {
os << "{";
bool commoFlag = false;
for (auto const& obj : objs) {
os << (commoFlag ? ", " : "") << obj;
commoFlag = true;
}
os << "}";
return os;
}
vector<float> f_vec{ 1.3f , 5.134f, 5.78f };
list<char> c_lst{ 'F','O', 'M', 'S', 'A' };
set<int> i_st{ 17,14, -70 };
std::cout << f_vec << std::endl;
std::cout << c_lst << std::endl;
std::cout << i_st << std::endl;
output:
{1.3, 5.134, 5.78}
{F, O, M, S, A}
{-70, 14, 17}
Using typedef in C++ creates an alias for a type.
So:
typedef double Length;
typedef double Mass;
creates two aliases which can be intermixed. In other words we can pass a value of type Mass to a function that expects a value of type Length.
Is there a lightweight way of creating new types? I would like them to be double underneath but be "different" so that one can't be used in place of another.
I would prefer something lighter than creating a new class or struct. Also, I am aware of the dimensions lib in boost. This is more complex and does a lot more than I need.
BOOST_STRONG_TYPEDEF seems to be designed exactly for what you're looking for. I believe it does it's magic by creating a class and overloading the operators to make it behave like a builtin type, but I've not looked at it's implementation.
While BOOST_STRONG_TYPEDEF is a pretty simple solution, if you're mixing lengths and masses into more complicated units (e.g. in the physical sciences) then you might want to use Boost.Units.
One other possible answer in C++11 is to use enum class : type. This will allow you to do what you want but it has its own downsides. For example you would have to overload a lot of operators.
#include <iostream>
#include <string>
enum class A : int;
enum class B : int;
std::ostream& operator<<(std::ostream& os, const A& t){
os << static_cast<int>(t);
return os;
}
std::ostream& operator<<(std::ostream& os, const B& t){
os << static_cast<int>(t);
return os;
}
int test(A t){
std::cout << "A " << t << std::endl;
return 0;
}
int test(B t){
std::cout << "B " << t << std::endl;
return 0;
}
int main(){
A a{static_cast<A>(42)};
B b{static_cast<B>(0)};
test(a);
test(b);
}
This would give the output of:
A 42
B 0
Or you could just get the integer part like this
template<class T>
int GetInt(T t)
{
return static_cast<int>(t);
}
std::cout << "B " << GetInt(t) << std::endl;
If the Metaclasses proposal (p7070) goes through (right now it's still at revision0), then we shall be able to create strong typedefs using an empty metaclass. Proposed syntax:
$class strong_typedef { };
using Length = $double.as(strong_typedef);
using Mass = $double.as(strong_typedef);
Earliest we might see this would be C++20