operator<< for std::vector< boost::variant< type_a, type_b >>

Dear boost-savvy people, I fail to understand how I need to write a working ostream overload for a type I have. I've read the boost::variant documentation. As well as stackoverflow question: https://stackoverflow.com/questions/46343138/using-stdvectorboostvariant-wit... Still I fail to understand how to make it work for the type I have. In the code you can see parameter_t is an element in the employee_t. I need to keep this data structure this way. Attached is my single 30 line problem code. I do compile with gcc 5.1.0 with C++14 support. It doesn't compile. The important part of the compiler output might be: C:\dev\boost_1_67_0/boost/variant/detail/variant_io.hpp:64:14: error: no match for 'operator<<' (operand types are 'std::basic_ostream<char>' and 'const std::vector<boost::variant<int, double> >') out_ << operand; My overload is obviously wrong. I would be very happy if someone can show me how to make it work. Best regards, Maarten Verhage

On Mon, Jun 18, 2018 at 2:55 PM, Maarten Verhage via Boost-users <boost-users@lists.boost.org> wrote:
Dear boost-savvy people,
I fail to understand how I need to write a working ostream overload for a type I have. I've read the boost::variant documentation. As well as stackoverflow question:
Not really a Boost question, per se: See "Stream extraction and insertion" in: http://en.cppreference.com/w/cpp/language/operators Basically, you need the stream reference as the first parameter, followed by whatever it is you are inserting, etc. Remember to return the stream reference. After that, decompose as needed for the complexity of your subject.
https://stackoverflow.com/questions/46343138/using-stdvectorboostvariant-wit...
Still I fail to understand how to make it work for the type I have. In the code you can see parameter_t is an element in the employee_t. I need to keep this data structure this way.
Attached is my single 30 line problem code. I do compile with gcc 5.1.0 with C++14 support.
It doesn't compile. The important part of the compiler output might be: C:\dev\boost_1_67_0/boost/variant/detail/variant_io.hpp:64:14: error: no match for 'operator<<' (operand types are 'std::basic_ostream<char>' and 'const std::vector<boost::variant<int, double> >') out_ << operand;
My overload is obviously wrong. I would be very happy if someone can show me how to make it work.
Best regards, Maarten Verhage
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users

----- Original Message ----- From: "Michael Powell via Boost-users" <boost-users@lists.boost.org> To: <boost-users@lists.boost.org> Cc: "Michael Powell" <mwpowellhtx@gmail.com> Sent: Monday, June 18, 2018 21:51 Subject: Re: [Boost-users] operator<< for std::vector< boost::variant< type_a, type_b >>
On Mon, Jun 18, 2018 at 2:55 PM, Maarten Verhage via Boost-users <boost-users@lists.boost.org> wrote:
Dear boost-savvy people,
I fail to understand how I need to write a working ostream overload for a type I have. I've read the boost::variant documentation. As well as stackoverflow question:
Not really a Boost question, per se:
See "Stream extraction and insertion" in:
http://en.cppreference.com/w/cpp/language/operators
Basically, you need the stream reference as the first parameter, followed by whatever it is you are inserting, etc. Remember to return the stream reference.
After that, decompose as needed for the complexity of your subject.
https://stackoverflow.com/questions/46343138/using-stdvectorboostvariant-wit...
boost::variant is obviously part of boost. And the compiler error is pointing in a variant header. So I'm pretty confident "Boost users" in the appropriate mailing list for this issue. You know, I sense some resentment against me. Can you clarify please? If you opened the attachment you can see I'm already at that level. And according to the stackoverflow answer for a very much related issue the solution is some next level stuff.
Still I fail to understand how to make it work for the type I have. In the code you can see parameter_t is an element in the employee_t. I need to keep this data structure this way.
Attached is my single 30 line problem code. I do compile with gcc 5.1.0 with C++14 support.
It doesn't compile. The important part of the compiler output might be: C:\dev\boost_1_67_0/boost/variant/detail/variant_io.hpp:64:14: error: no match for 'operator<<' (operand types are 'std::basic_ostream<char>' and 'const std::vector<boost::variant<int, double> >') out_ << operand;
My overload is obviously wrong. I would be very happy if someone can show me how to make it work.
Best regards, Maarten Verhage
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users

On Mon, Jun 18, 2018 at 3:20 PM Maarten Verhage via Boost-users < boost-users@lists.boost.org> wrote:
boost::variant is obviously part of boost. And the compiler error is pointing in a variant header. So I'm pretty confident "Boost users" in the appropriate mailing list for this issue.
Except for the fact that it's not. I looked at the code, and I suspect you've ended up confusing yourself. In particular, your typedefs are confusing. Are you sure you didn't mean this? It looks like you did based on the rest of the code. typedef boost::variant< int, double > parameter_t; typedef std::vector< parameter_t > employee_t; In other words, a vector (type `employee_t`) where each element is a variant of either `int` or `double`. If that's what you meant to type, then compiling with clang++ -std=c++14 creates an a.out that prints "306000" as expected.
You know, I sense some resentment against me. Can you clarify please?
I didn't. In fact, he answered your question by giving you references to documentation based on the error message you presented. Unfortunately I think that error message was a red herring.
If you opened the attachment you can see I'm already at that level. And according to the stackoverflow answer for a very much related issue the solution is some next level stuff.
Fortunately, I suspect that the solution really just involves fixing your types. -- Chris Cleeland

On Mon, Jun 18, 2018 at 4:51 PM, Chris Cleeland via Boost-users <boost-users@lists.boost.org> wrote:
On Mon, Jun 18, 2018 at 3:20 PM Maarten Verhage via Boost-users <boost-users@lists.boost.org> wrote:
boost::variant is obviously part of boost. And the compiler error is pointing in a variant header. So I'm pretty confident "Boost users" in the appropriate mailing list for this issue.
Except for the fact that it's not. I looked at the code, and I suspect you've ended up confusing yourself.
In particular, your typedefs are confusing. Are you sure you didn't mean this? It looks like you did based on the rest of the code.
typedef boost::variant< int, double > parameter_t; typedef std::vector< parameter_t > employee_t;
In other words, a vector (type `employee_t`) where each element is a variant of either `int` or `double`.
If that's what you meant to type, then compiling with clang++ -std=c++14 creates an a.out that prints "306000" as expected.
You know, I sense some resentment against me. Can you clarify please?
I didn't. In fact, he answered your question by giving you references to documentation based on the error message you presented. Unfortunately I think that error message was a red herring.
Glad to help. Consider it on the table, rule it out if it isn't useful to you, or in this case helps to narrow the root cause, or whatever. Completely up to you.
If you opened the attachment you can see I'm already at that level. And according to the stackoverflow answer for a very much related issue the solution is some next level stuff.
Fortunately, I suspect that the solution really just involves fixing your types.
-- Chris Cleeland
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users

----- Original Message ----- From: "Michael Powell via Boost-users" <boost-users@lists.boost.org> To: <boost-users@lists.boost.org> Cc: "Michael Powell" <mwpowellhtx@gmail.com> Sent: Monday, June 18, 2018 23:00 Subject: Re: [Boost-users] operator<< for std::vector< boost::variant< type_a, type_b >>
On Mon, Jun 18, 2018 at 4:51 PM, Chris Cleeland via Boost-users <boost-users@lists.boost.org> wrote:
On Mon, Jun 18, 2018 at 3:20 PM Maarten Verhage via Boost-users <boost-users@lists.boost.org> wrote:
boost::variant is obviously part of boost. And the compiler error is pointing in a variant header. So I'm pretty confident "Boost users" in the appropriate mailing list for this issue.
Except for the fact that it's not. I looked at the code, and I suspect you've ended up confusing yourself.
In particular, your typedefs are confusing. Are you sure you didn't mean this? It looks like you did based on the rest of the code.
typedef boost::variant< int, double > parameter_t; typedef std::vector< parameter_t > employee_t;
I'm actually pursuing this tree-like hierarchy. I might even need to make it recursive. But I want to start easy. typedef std::vector< boost::variant< int, double >> parameter_t; typedef std::vector< boost::variant< int, double, parameter_t >> employee_t; Have you looked into the stackoverflow answer by: Richard Hodges? The poster had the same compiler error and the solution Richard presented is significantly more complicated than a single operator<< overload.
In other words, a vector (type `employee_t`) where each element is a variant of either `int` or `double`.
If that's what you meant to type, then compiling with clang++ -std=c++14 creates an a.out that prints "306000" as expected.
You know, I sense some resentment against me. Can you clarify please?
I didn't. In fact, he answered your question by giving you references to documentation based on the error message you presented. Unfortunately I think that error message was a red herring.
Glad to help. Consider it on the table, rule it out if it isn't useful to you, or in this case helps to narrow the root cause, or whatever. Completely up to you.
If you opened the attachment you can see I'm already at that level. And according to the stackoverflow answer for a very much related issue the solution is some next level stuff.
Fortunately, I suspect that the solution really just involves fixing your types.
-- Chris Cleeland
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users

On Mon, Jun 18, 2018 at 5:22 PM, Maarten Verhage via Boost-users <boost-users@lists.boost.org> wrote:
----- Original Message ----- From: "Michael Powell via Boost-users" <boost-users@lists.boost.org> To: <boost-users@lists.boost.org> Cc: "Michael Powell" <mwpowellhtx@gmail.com> Sent: Monday, June 18, 2018 23:00 Subject: Re: [Boost-users] operator<< for std::vector< boost::variant< type_a, type_b >>
On Mon, Jun 18, 2018 at 4:51 PM, Chris Cleeland via Boost-users <boost-users@lists.boost.org> wrote:
On Mon, Jun 18, 2018 at 3:20 PM Maarten Verhage via Boost-users <boost-users@lists.boost.org> wrote:
boost::variant is obviously part of boost. And the compiler error is pointing in a variant header. So I'm pretty confident "Boost users" in the appropriate mailing list for this issue.
Except for the fact that it's not. I looked at the code, and I suspect you've ended up confusing yourself.
In particular, your typedefs are confusing. Are you sure you didn't mean this? It looks like you did based on the rest of the code.
typedef boost::variant< int, double > parameter_t; typedef std::vector< parameter_t > employee_t;
I'm actually pursuing this tree-like hierarchy. I might even need to make it recursive. But I want to start easy.
typedef std::vector< boost::variant< int, double >> parameter_t; typedef std::vector< boost::variant< int, double, parameter_t >> employee_t;
Have you looked into the stackoverflow answer by: Richard Hodges? The poster had the same compiler error and the solution Richard presented is significantly more complicated than a single operator<< overload.
To be perfectly clear, I'm not sure what you're fishing for here, and I am definitely not here to analyze nor troubleshoot your code. But, there did seem to be at least a general question about operator overloading. What you do with that knowledge in your specific case is entirely up to you. I'm not at liberty to discuss beyond that.
In other words, a vector (type `employee_t`) where each element is a variant of either `int` or `double`.
If that's what you meant to type, then compiling with clang++ -std=c++14 creates an a.out that prints "306000" as expected.
You know, I sense some resentment against me. Can you clarify please?
I didn't. In fact, he answered your question by giving you references to documentation based on the error message you presented. Unfortunately I think that error message was a red herring.
Glad to help. Consider it on the table, rule it out if it isn't useful to you, or in this case helps to narrow the root cause, or whatever. Completely up to you.
If you opened the attachment you can see I'm already at that level. And according to the stackoverflow answer for a very much related issue the solution is some next level stuff.
Fortunately, I suspect that the solution really just involves fixing your types.
-- Chris Cleeland
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users

On Mon, Jun 18, 2018 at 4:23 PM Maarten Verhage via Boost-users < boost-users@lists.boost.org> wrote:
In particular, your typedefs are confusing. Are you sure you didn't mean this? It looks like you did based on the rest of the code.
typedef boost::variant< int, double > parameter_t; typedef std::vector< parameter_t > employee_t;
I'm actually pursuing this tree-like hierarchy. I might even need to make it recursive. But I want to start easy.
typedef std::vector< boost::variant< int, double >> parameter_t; typedef std::vector< boost::variant< int, double, parameter_t >> employee_t;
Strange structure, but okay.
Have you looked into the stackoverflow answer by: Richard Hodges? The poster had the same compiler error and the solution Richard presented is significantly more complicated than a single operator<< overload.
Yes I did. He tells you the answer--that boost::variant's auto-io visit looks for an ADL-found operator<< for the types, and, as your compiler tells you, it can't find one for std::vector<blah>. Because it's ADL-found, the operators you defined at global scope will never match. They will only be found if they are defined in namespace std or in whatever namespace contains the compile-time invocation of operator<<. As the stackoverflow answer indicates, neither is a really great idea, because it's a violation of the standard to introduce anything into namespace std, and introducing it into the invoking namespace requires knowing the invoking namespace--which is an implementation detail of boost::variant and may change or may even vary depending on the types used. For grins I used your original and put two operator<< inside `namespace std`--one for each of your typedefs. The compiler found them both and created an executable that ran. Good luck. -- Chris Cleeland

----- Original Message ----- From: Chris Cleeland via Boost-users<mailto:boost-users@lists.boost.org> To: boost-users<mailto:boost-users@lists.boost.org> Cc: Chris Cleeland<mailto:chris.cleeland@gmail.com> Sent: Monday, June 18, 2018 23:56 Subject: Re: [Boost-users] operator<< for std::vector< boost::variant< type_a, type_b >> On Mon, Jun 18, 2018 at 4:23 PM Maarten Verhage via Boost-users <boost-users@lists.boost.org<mailto:boost-users@lists.boost.org>> wrote:
In particular, your typedefs are confusing. Are you sure you didn't mean this? It looks like you did based on the rest of the code.
typedef boost::variant< int, double > parameter_t; typedef std::vector< parameter_t > employee_t;
I'm actually pursuing this tree-like hierarchy. I might even need to make it recursive. But I want to start easy. typedef std::vector< boost::variant< int, double >> parameter_t; typedef std::vector< boost::variant< int, double, parameter_t >> employee_t; Strange structure, but okay. Have you looked into the stackoverflow answer by: Richard Hodges? The poster had the same compiler error and the solution Richard presented is significantly more complicated than a single operator<< overload. Yes I did. He tells you the answer--that boost::variant's auto-io visit looks for an ADL-found operator<< for the types, and, as your compiler tells you, it can't find one for std::vector<blah>. Because it's ADL-found, the operators you defined at global scope will never match. They will only be found if they are defined in namespace std or in whatever namespace contains the compile-time invocation of operator<<. As the stackoverflow answer indicates, neither is a really great idea, because it's a violation of the standard to introduce anything into namespace std, and introducing it into the invoking namespace requires knowing the invoking namespace--which is an implementation detail of boost::variant and may change or may even vary depending on the types used. For grins I used your original and put two operator<< inside `namespace std`--one for each of your typedefs. The compiler found them both and created an executable that ran. Good luck. -- Chris Cleeland ________________________________ Thanks Chris, Make if '<<' isn't so suitable. I can better make it work with the visitor and not using the << operator to sent it to ostream. Regards, Maarten
participants (3)
-
Chris Cleeland
-
Maarten Verhage
-
Michael Powell