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

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

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

Boost - Users mailing list
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:
 
 
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
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users

test.cpp (958 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

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

Boost - Users mailing list
On Mon, Jun 18, 2018 at 2:55 PM, Maarten Verhage via Boost-users
<[hidden email]> 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-with-google-mock-causes-a-compilation-err
>
> 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
> [hidden email]
> https://lists.boost.org/mailman/listinfo.cgi/boost-users
>
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

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

Boost - Users mailing list

----- Original Message -----
From: "Michael Powell via Boost-users" <[hidden email]>
To: <[hidden email]>
Cc: "Michael Powell" <[hidden email]>
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
> <[hidden email]> 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-with-google-mock-causes-a-compilation-err
>>

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
>> [hidden email]
>> https://lists.boost.org/mailman/listinfo.cgi/boost-users
>>
> _______________________________________________
> Boost-users mailing list
> [hidden email]
> https://lists.boost.org/mailman/listinfo.cgi/boost-users
>

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

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

Boost - Users mailing list


On Mon, Jun 18, 2018 at 3:20 PM Maarten Verhage via Boost-users <[hidden email]> 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

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

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

Boost - Users mailing list
On Mon, Jun 18, 2018 at 4:51 PM, Chris Cleeland via Boost-users
<[hidden email]> wrote:

>
>
> On Mon, Jun 18, 2018 at 3:20 PM Maarten Verhage via Boost-users
> <[hidden email]> 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
> [hidden email]
> https://lists.boost.org/mailman/listinfo.cgi/boost-users
>
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

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

Boost - Users mailing list

----- Original Message -----
From: "Michael Powell via Boost-users" <[hidden email]>
To: <[hidden email]>
Cc: "Michael Powell" <[hidden email]>
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
> <[hidden email]> wrote:
>>
>>
>> On Mon, Jun 18, 2018 at 3:20 PM Maarten Verhage via Boost-users
>> <[hidden email]> 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
>> [hidden email]
>> https://lists.boost.org/mailman/listinfo.cgi/boost-users
>>
> _______________________________________________
> Boost-users mailing list
> [hidden email]
> https://lists.boost.org/mailman/listinfo.cgi/boost-users
>

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

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

Boost - Users mailing list
On Mon, Jun 18, 2018 at 5:22 PM, Maarten Verhage via Boost-users
<[hidden email]> wrote:

>
> ----- Original Message -----
> From: "Michael Powell via Boost-users" <[hidden email]>
> To: <[hidden email]>
> Cc: "Michael Powell" <[hidden email]>
> 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
>> <[hidden email]> wrote:
>>>
>>>
>>> On Mon, Jun 18, 2018 at 3:20 PM Maarten Verhage via Boost-users
>>> <[hidden email]> 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
>>> [hidden email]
>>> https://lists.boost.org/mailman/listinfo.cgi/boost-users
>>>
>> _______________________________________________
>> Boost-users mailing list
>> [hidden email]
>> https://lists.boost.org/mailman/listinfo.cgi/boost-users
>>
>
> _______________________________________________
> Boost-users mailing list
> [hidden email]
> https://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

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

Boost - Users mailing list
In reply to this post by Boost - Users mailing list


On Mon, Jun 18, 2018 at 4:23 PM Maarten Verhage via Boost-users <[hidden email]> 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

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

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

Boost - Users mailing list
 
----- Original Message -----
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 <[hidden email]> 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

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users