Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #119544 > unrolled thread
| Started by | wij <wyniijj5@gmail.com> |
|---|---|
| First post | 2024-06-28 01:42 +0800 |
| Last post | 2024-07-20 20:18 -0700 |
| Articles | 20 on this page of 42 — 8 participants |
Back to article view | Back to comp.lang.c++
How to implement Foo:swap wij <wyniijj5@gmail.com> - 2024-06-28 01:42 +0800
Re: How to implement Foo:swap Bonita Montero <Bonita.Montero@gmail.com> - 2024-06-27 19:53 +0200
Re: How to implement Foo:swap Bonita Montero <Bonita.Montero@gmail.com> - 2024-06-27 19:57 +0200
Re: How to implement Foo:swap red floyd <no.spam.here@its.invalid> - 2024-06-27 14:02 -0700
Re: How to implement Foo:swap wij <wyniijj5@gmail.com> - 2024-06-28 08:51 +0800
Re: How to implement Foo:swap red floyd <no.spam.here@its.invalid> - 2024-06-27 21:46 -0700
Re: How to implement Foo:swap red floyd <no.spam.here@its.invalid> - 2024-06-27 21:53 -0700
Re: How to implement Foo:swap Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-06-28 11:04 -0700
Re: How to implement Foo:swap Paavo Helde <eesnimi@osa.pri.ee> - 2024-06-28 00:04 +0300
Re: How to implement Foo:swap Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-06-27 22:21 -0700
Re: How to implement Foo:swap Bonita Montero <Bonita.Montero@gmail.com> - 2024-06-28 10:16 +0200
Re: How to implement Foo:swap Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-06-28 09:33 -0700
Re: How to implement Foo:swap Bonita Montero <Bonita.Montero@gmail.com> - 2024-06-28 23:51 +0200
Re: How to implement Foo:swap Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-06-28 15:23 -0700
Re: How to implement Foo:swap Bonita Montero <Bonita.Montero@gmail.com> - 2024-06-29 12:12 +0200
Re: How to implement Foo:swap Bonita Montero <Bonita.Montero@gmail.com> - 2024-06-29 15:03 +0200
Re: How to implement Foo:swap Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-06-29 08:59 -0700
Re: How to implement Foo:swap Bonita Montero <Bonita.Montero@gmail.com> - 2024-06-29 19:04 +0200
Re: How to implement Foo:swap Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-06-29 10:27 -0700
Re: How to implement Foo:swap Bonita Montero <Bonita.Montero@gmail.com> - 2024-06-29 19:52 +0200
Re: How to implement Foo:swap "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-06-29 12:33 -0700
Re: How to implement Foo:swap "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-06-29 12:34 -0700
Re: How to implement Foo:swap Richard Damon <richard@damon-family.org> - 2024-06-29 16:13 -0400
Re: How to implement Foo:swap "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-06-29 13:52 -0700
Re: How to implement Foo:swap Bonita Montero <Bonita.Montero@gmail.com> - 2024-06-30 00:38 +0200
Re: How to implement Foo:swap "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-06-29 18:09 -0700
Re: How to implement Foo:swap Bonita Montero <Bonita.Montero@gmail.com> - 2024-06-29 19:22 +0200
Re: How to implement Foo:swap Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-06-29 10:43 -0700
Re: How to implement Foo:swap Bonita Montero <Bonita.Montero@gmail.com> - 2024-06-29 19:49 +0200
Re: How to implement Foo:swap Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-06-29 11:03 -0700
Re: How to implement Foo:swap Bonita Montero <Bonita.Montero@gmail.com> - 2024-06-29 20:08 +0200
Re: How to implement Foo:swap Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-06-29 11:24 -0700
Re: How to implement Foo:swap Bonita Montero <Bonita.Montero@gmail.com> - 2024-06-29 20:46 +0200
Re: How to implement Foo:swap Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-06-29 20:48 -0700
Re: How to implement Foo:swap Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-06-29 08:55 -0700
Re: How to implement Foo:swap Bonita Montero <Bonita.Montero@gmail.com> - 2024-06-29 19:05 +0200
Re: How to implement Foo:swap Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-06-29 10:35 -0700
Re: How to implement Foo:swap Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-06-29 09:15 -0700
Re: How to implement Foo:swap Marcel Mueller <news.5.maazl@spamgourmet.org> - 2024-07-15 20:33 +0200
Re: How to implement Foo:swap Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-07-15 20:04 -0700
Re: How to implement Foo:swap Marcel Mueller <news.5.maazl@spamgourmet.org> - 2024-07-20 13:19 +0200
Re: How to implement Foo:swap Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-07-20 20:18 -0700
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2024-06-29 12:33 -0700 |
| Message-ID | <v5pni5$2b21$4@dont-email.me> |
| In reply to | #119566 |
On 6/29/2024 10:04 AM, Bonita Montero wrote: > Am 29.06.2024 um 17:59 schrieb Andrey Tarasevich: >> On 06/29/24 6:03 AM, Bonita Montero wrote: >>> And usually I place the swap-code into the std-namespace, specialized >>> for my custom data structure so that if so explicitly uses std::swap >>> this still works. >> >> A very ugly idea. > > It's not ugly because std::swap will never be specialized for my own > datastructure in the global namespace. And you can be assured that if > someone uses std::swap prefixed on your own data structure that this > works. [...] Injecting anything into the std namesapce is bad. ;^o >
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2024-06-29 12:34 -0700 |
| Message-ID | <v5pnjt$2b21$5@dont-email.me> |
| In reply to | #119578 |
On 6/29/2024 12:33 PM, Chris M. Thomasson wrote:
> On 6/29/2024 10:04 AM, Bonita Montero wrote:
>> Am 29.06.2024 um 17:59 schrieb Andrey Tarasevich:
>>> On 06/29/24 6:03 AM, Bonita Montero wrote:
>>>> And usually I place the swap-code into the std-namespace, specialized
>>>> for my custom data structure so that if so explicitly uses std::swap
>>>> this still works.
>>>
>>> A very ugly idea.
>>
>> It's not ugly because std::swap will never be specialized for my own
>> datastructure in the global namespace. And you can be assured that if
>> someone uses std::swap prefixed on your own data structure that this
>> works.
> [...]
>
> Injecting anything into the std namesapce is bad. ;^o
>
>>
>
namespace std
{
// add things
}
No! Bad mojo.
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <richard@damon-family.org> |
|---|---|
| Date | 2024-06-29 16:13 -0400 |
| Message-ID | <v5ppu2$1gd9d$1@i2pn2.org> |
| In reply to | #119578 |
On 6/29/24 3:33 PM, Chris M. Thomasson wrote: > On 6/29/2024 10:04 AM, Bonita Montero wrote: >> Am 29.06.2024 um 17:59 schrieb Andrey Tarasevich: >>> On 06/29/24 6:03 AM, Bonita Montero wrote: >>>> And usually I place the swap-code into the std-namespace, specialized >>>> for my custom data structure so that if so explicitly uses std::swap >>>> this still works. >>> >>> A very ugly idea. >> >> It's not ugly because std::swap will never be specialized for my own >> datastructure in the global namespace. And you can be assured that if >> someone uses std::swap prefixed on your own data structure that this >> works. > [...] > > Injecting anything into the std namesapce is bad. ;^o > >> > But the Standard SPECIFICALLY allows for it, as long as the Injected item is a specialization/overload of a defined thing using a user defined type in the specialization/overload.
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2024-06-29 13:52 -0700 |
| Message-ID | <v5ps6a$3csi$1@dont-email.me> |
| In reply to | #119580 |
On 6/29/2024 1:13 PM, Richard Damon wrote: > On 6/29/24 3:33 PM, Chris M. Thomasson wrote: >> On 6/29/2024 10:04 AM, Bonita Montero wrote: >>> Am 29.06.2024 um 17:59 schrieb Andrey Tarasevich: >>>> On 06/29/24 6:03 AM, Bonita Montero wrote: >>>>> And usually I place the swap-code into the std-namespace, specialized >>>>> for my custom data structure so that if so explicitly uses std::swap >>>>> this still works. >>>> >>>> A very ugly idea. >>> >>> It's not ugly because std::swap will never be specialized for my own >>> datastructure in the global namespace. And you can be assured that if >>> someone uses std::swap prefixed on your own data structure that this >>> works. >> [...] >> >> Injecting anything into the std namesapce is bad. ;^o >> >>> >> > > But the Standard SPECIFICALLY allows for it, as long as the Injected > item is a specialization/overload of a defined thing using a user > defined type in the specialization/overload. I, personally, do not like to do that.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2024-06-30 00:38 +0200 |
| Message-ID | <v5q2de$4m2s$1@raubtier-asyl.eternal-september.org> |
| In reply to | #119578 |
Am 29.06.2024 um 21:33 schrieb Chris M. Thomasson: > On 6/29/2024 10:04 AM, Bonita Montero wrote: >> Am 29.06.2024 um 17:59 schrieb Andrey Tarasevich: >>> On 06/29/24 6:03 AM, Bonita Montero wrote: >>>> And usually I place the swap-code into the std-namespace, specialized >>>> for my custom data structure so that if so explicitly uses std::swap >>>> this still works. >>> >>> A very ugly idea. >> >> It's not ugly because std::swap will never be specialized for my own >> datastructure in the global namespace. And you can be assured that if >> someone uses std::swap prefixed on your own data structure that this >> works. > [...] > > Injecting anything into the std namesapce is bad. ;^o Not if the specialization doesn't collide with the namespace's definitions.
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2024-06-29 18:09 -0700 |
| Message-ID | <v5qb7c$67h8$2@dont-email.me> |
| In reply to | #119582 |
On 6/29/2024 3:38 PM, Bonita Montero wrote: > Am 29.06.2024 um 21:33 schrieb Chris M. Thomasson: >> On 6/29/2024 10:04 AM, Bonita Montero wrote: >>> Am 29.06.2024 um 17:59 schrieb Andrey Tarasevich: >>>> On 06/29/24 6:03 AM, Bonita Montero wrote: >>>>> And usually I place the swap-code into the std-namespace, specialized >>>>> for my custom data structure so that if so explicitly uses std::swap >>>>> this still works. >>>> >>>> A very ugly idea. >>> >>> It's not ugly because std::swap will never be specialized for my own >>> datastructure in the global namespace. And you can be assured that if >>> someone uses std::swap prefixed on your own data structure that this >>> works. >> [...] >> >> Injecting anything into the std namesapce is bad. ;^o > > Not if the specialization doesn't collide with the namespace's > definitions. > If a team I was working with is doing it, I would say, uggg, okay! Let's go. However, personally, I don't like to inject things into the std namespace.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2024-06-29 19:22 +0200 |
| Message-ID | <v5pfst$14il$1@raubtier-asyl.eternal-september.org> |
| In reply to | #119564 |
Now it works:
#include <iostream>
using namespace std;
template<typename T>
struct Foo
{
private:
T m_val;
template<typename T2>
friend void swap( Foo<T2> &lhs, Foo<T2> &rhs ) noexcept;
};
template<typename T>
void swap( Foo<T> &lhs, Foo<T> &rhs ) noexcept
{
T t = lhs.m_val;
lhs.m_val = rhs.m_val;
rhs.m_val = t;
}
int main()
{
Foo<string> fsA, fsB;
::swap( fsA, fsB );
}
The only disadvantage with the code is that all swaps for different Ts /
T2s can access the m_val in Foo.
I've got no problem to inject a swap into std unless it is only
specified for std't types.
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2024-06-29 10:43 -0700 |
| Message-ID | <v5ph47$13e5$3@dont-email.me> |
| In reply to | #119568 |
On 06/29/24 10:22 AM, Bonita Montero wrote:
> Now it works:
>
> #include <iostream>
>
> using namespace std;
>
> template<typename T>
> struct Foo
> {
> private:
> T m_val;
> template<typename T2>
> friend void swap( Foo<T2> &lhs, Foo<T2> &rhs ) noexcept;
> };
>
> template<typename T>
> void swap( Foo<T> &lhs, Foo<T> &rhs ) noexcept
> {
> T t = lhs.m_val;
> lhs.m_val = rhs.m_val;
> rhs.m_val = t;
> }
>
> int main()
> {
> Foo<string> fsA, fsB;
> ::swap( fsA, fsB );
> }
>
> The only disadvantage with the code is that all swaps for different Ts /
> T2s can access the m_val in Foo.
>
> I've got no problem to inject a swap into std unless it is only
> specified for std't types.
Here it is. Now you finally managed to provide a in-class friend
declaration that properly matches the out-of-class definition.
* Firstly, this has a lot more syntactic clutter.
* Secondly, as you already noted, it grants unnecessary cross-friendship
(this second problem can be solved (by adding a bit more clutter).
Now compare it with mine
template<typename T>
struct Foo
{
private:
T m_val;
friend void swap(Foo &lhs, Foo &rhs) noexcept
{
T t = lhs.m_val;
lhs.m_val = rhs.m_val;
rhs.m_val = t;
}
};
This is a lot cleaner.
Now, I'm not a big fan of multiline in-class member definitions. But, as
I said above, this `swap` cannot be defined out-of-class. The language
has no syntax for it.
--
Best regards,
Andrey
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2024-06-29 19:49 +0200 |
| Message-ID | <v5phel$1d3f$1@raubtier-asyl.eternal-september.org> |
| In reply to | #119571 |
Am 29.06.2024 um 19:43 schrieb Andrey Tarasevich:
> * Firstly, this has a lot more syntactic clutter.
I think my soulution is more readable and the declarative add-on doesn't
hurt.
>
> * Secondly, as you already noted, it grants unnecessary cross-friendship
> (this second problem can be solved (by adding a bit more clutter).
That's a theoretical problem.
> Now compare it with mine
>
> template<typename T>
> struct Foo
> {
> private:
> T m_val;
>
> friend void swap(Foo &lhs, Foo &rhs) noexcept
> {
> T t = lhs.m_val;
> lhs.m_val = rhs.m_val;
> rhs.m_val = t;
> }
> };
>
> This is a lot cleaner.
For me absolutely not because I like out-of-class definitions which
make the class itself more readable. Usually classes are much longer
that this counts.
> Now, I'm not a big fan of multiline in-class member definitions. But, as
> I said above, this `swap` cannot be defined out-of-class. The language
> has no syntax for it.
I've shown the syntax.
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2024-06-29 11:03 -0700 |
| Message-ID | <v5pi8q$1esa$1@dont-email.me> |
| In reply to | #119572 |
On 06/29/24 10:49 AM, Bonita Montero wrote:
>
> I've shown the syntax.
>
Apparently there's no hope...
You've shown the syntax for *template* `swap`. Meanwhile, I'm stating
that there's no syntax for defining a *non-template* `swap` out-of-class.
See the difference?
We are talking about two completely different things. Yes, it is a
rather intricate and dark corner of C++ semantics, but I hoped you'd
grasp it by now.
Here's a little educational example for you (for GCC, since it uses
`__PRETTY_FUNCTION__`)
#include <iostream>
template <typename T> struct S
{
friend void foo(S &)
{ std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
template <typename T> void bar(S<T> &)
{ std::cout << __PRETTY_FUNCTION__ << std::endl; }
int main()
{
S<int> s;
foo(s);
bar(s);
}
The code outputs the follwing
void foo(S<int>&)
void bar(S<T>&) [with T = int]
https://coliru.stacked-crooked.com/a/3fccf6372dfe21e7
Now, the little detail I want to draw your attention to is what
`__PRETTY_FUNCTION__` outputs for these two functions. See that `[...]`
part in the `bar`s output? Wonder why it is missing in the `foo`s output?
In our original `swap` problem I want a `foo`-like `swap`, not
`bar`-like. I want a solution that has no `[...]` in the
`__PRETTY_FUNCTION__`.
--
Best regards,
Andrey
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2024-06-29 20:08 +0200 |
| Message-ID | <v5pij4$1kdr$1@raubtier-asyl.eternal-september.org> |
| In reply to | #119574 |
Am 29.06.2024 um 20:03 schrieb Andrey Tarasevich: > On 06/29/24 10:49 AM, Bonita Montero wrote: >> >> I've shown the syntax. >> > > Apparently there's no hope... > > You've shown the syntax for *template* `swap`. ... That's a sufficient solution for the same thing.
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2024-06-29 11:24 -0700 |
| Message-ID | <v5pjh0$1pq0$1@dont-email.me> |
| In reply to | #119575 |
On 06/29/24 11:08 AM, Bonita Montero wrote: > Am 29.06.2024 um 20:03 schrieb Andrey Tarasevich: >> On 06/29/24 10:49 AM, Bonita Montero wrote: >>> >>> I've shown the syntax. >>> >> >> Apparently there's no hope... >> >> You've shown the syntax for *template* `swap`. ... > > That's a sufficient solution for the same thing. It is. But that's not the issue I was talking about. -- Best regards, Andrey
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2024-06-29 20:46 +0200 |
| Message-ID | <v5pkp9$21dn$1@raubtier-asyl.eternal-september.org> |
| In reply to | #119576 |
Am 29.06.2024 um 20:24 schrieb Andrey Tarasevich: > On 06/29/24 11:08 AM, Bonita Montero wrote: >> Am 29.06.2024 um 20:03 schrieb Andrey Tarasevich: >>> On 06/29/24 10:49 AM, Bonita Montero wrote: >>>> >>>> I've shown the syntax. >>>> >>> >>> Apparently there's no hope... >>> >>> You've shown the syntax for *template* `swap`. ... >> >> That's a sufficient solution for the same thing. > > It is. But that's not the issue I was talking about. For me this issue doesn't exist because I know a solution with issues that don't hurt.
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2024-06-29 20:48 -0700 |
| Message-ID | <v5qkj8$bfb3$1@dont-email.me> |
| In reply to | #119577 |
On 06/29/24 11:46 AM, Bonita Montero wrote:
> Am 29.06.2024 um 20:24 schrieb Andrey Tarasevich:
>> On 06/29/24 11:08 AM, Bonita Montero wrote:
>>> Am 29.06.2024 um 20:03 schrieb Andrey Tarasevich:
>>>> On 06/29/24 10:49 AM, Bonita Montero wrote:
>>>>>
>>>>> I've shown the syntax.
>>>>>
>>>>
>>>> Apparently there's no hope...
>>>>
>>>> You've shown the syntax for *template* `swap`. ...
>>>
>>> That's a sufficient solution for the same thing.
>>
>> It is. But that's not the issue I was talking about.
>
> For me this issue doesn't exist because I know a solution
> with issues that don't hurt.
That's fine.
In general case (also implying that we'll need non-public access), there
are three ways to define a friend to a template class
1. Non-template friend
template <typename T> class C
{
int i;
friend void foo(C &c) { c.i = 42; }
};
The definition has to be done in-class.
2. Template friend with loose friendship
template <typename T> class C
{
int i = 0;
template <typename U> friend void foo(C<U> &c) { c.i = 42; }
};
The definition can be done in-class or out-of-class.
3. Template friend with strict friendship
template <typename> class C;
template <typename T> void foo(C<T> &);
template <typename T> class C
{
int i = 0;
friend void foo<>(C &);
};
template <typename T> void foo(C<T> &c) { c.i = 42; }
The definition can only be done out-of-class, if I'm not mistaken.
You apparently prefer #2. I prefer #1.
--
Best regards,
Andrey
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2024-06-29 08:55 -0700 |
| Message-ID | <v5paqg$3vvn7$1@dont-email.me> |
| In reply to | #119561 |
On 06/29/24 3:12 AM, Bonita Montero wrote:
> Am 29.06.2024 um 00:23 schrieb Andrey Tarasevich:
>
>> As I already stated above, the language provides no other syntax for
>> achieving this objective besides the one based on `friend`.
>
> Works:
>
> #include <iostream>
>
> using namespace std;
>
> template<typename T>
> struct Foo
> {
> T m_val;
> friend void swap( Foo &lhs, Foo &rhs ) noexcept;
> };
>
> template<typename T>
> void swap( Foo<T> &lhs, Foo<T> &rhs ) noexcept
> {
> T t = lhs.m_val;
> lhs.m_val = rhs.m_val;
> rhs.m_val = t;
> }
>
Um...
Firstly, your code is not doing what you think it is doing. The `friend`
declaration in the class has no relation to the template declaration
outside the class. (Try making the members `private` and you'll
immediately see that your template has no access to them.)
The `friend` declaration plays no role whatsoever in your code. It is
not used at all. You can simply remove it - it won't change anything.
Secondly, you implemented `swap` as a separate template. Which is a
completely different thing from what I wanted. I don't want a separate
template. I want (and I repeat): a *non-template* `swap` function to be
automatically emitted by compiler for each specialization of `Foo<>`.
Mine is a completely different approach. And, (and I repeat) this can
only be done through a `friend` hack I described above.
--
Best regards,
Andrey
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2024-06-29 19:05 +0200 |
| Message-ID | <v5pesq$uo3$2@raubtier-asyl.eternal-september.org> |
| In reply to | #119563 |
Am 29.06.2024 um 17:55 schrieb Andrey Tarasevich:
> On 06/29/24 3:12 AM, Bonita Montero wrote:
>> Am 29.06.2024 um 00:23 schrieb Andrey Tarasevich:
>>
>>> As I already stated above, the language provides no other syntax for
>>> achieving this objective besides the one based on `friend`.
>>
>> Works:
>>
>> #include <iostream>
>>
>> using namespace std;
>>
>> template<typename T>
>> struct Foo
>> {
>> T m_val;
>> friend void swap( Foo &lhs, Foo &rhs ) noexcept;
>> };
>>
>> template<typename T>
>> void swap( Foo<T> &lhs, Foo<T> &rhs ) noexcept
>> {
>> T t = lhs.m_val;
>> lhs.m_val = rhs.m_val;
>> rhs.m_val = t;
>> }
>>
>
> Um...
>
> Firstly, your code is not doing what you think it is doing. ...
My own swap is called; I've tried that in the debugger.
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2024-06-29 10:35 -0700 |
| Message-ID | <v5pgl3$13e5$2@dont-email.me> |
| In reply to | #119567 |
On 06/29/24 10:05 AM, Bonita Montero wrote: > My own swap is called; I've tried that in the debugger. Yes, it is called. But what point are you trying to make? As I stated many times previously: my objective is to provide a dedicated *non-template* `swap` for each specialization of `Foo<>`. And I demonstrated how one can do that (through an in class `friend` definition). Your code provides a *template* `swap`. This is a completely different approach for solving the same problem. I like my approach better. There are objective reasons why it is better, but let's just take it as my caprice for now. I just want a *non-template* `swap`. -- Best regards, Andrey
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2024-06-29 09:15 -0700 |
| Message-ID | <v5pbuo$8qn$1@dont-email.me> |
| In reply to | #119561 |
On 06/29/24 3:12 AM, Bonita Montero wrote: > > Without :: before swap this doesn't work. > This is actually what should have made you realize that your in-class `friend` declaration and your out-of-class template `swap` declaration are completely unrelated. Without the `::`, the ADL finds the `friend` version of `swap`. The unqualified lookup prefers that `friend` version. So, it calls it. However, the `friend` version is not defined in your code. So, you end up with a linker error. And, as I said above, you can't define it out-of-class. The language provides no syntax for out-of-class definition of such friends. You can only do it inline, exactly as I do in my code sample. -- Best regards, Andrey
[toc] | [prev] | [next] | [standalone]
| From | Marcel Mueller <news.5.maazl@spamgourmet.org> |
|---|---|
| Date | 2024-07-15 20:33 +0200 |
| Message-ID | <v73q1s$g1at$1@gwaiyur.mb-net.net> |
| In reply to | #119554 |
Am 28.06.24 um 07:21 schrieb Andrey Tarasevich: > Firstly, when implementing a custom `swap` for your custom type it is a > better idea to implement it as a friend function Sometimes it can be useful to have a swap member function. E.g. when implementing assignment functions/operators the pattern Foo(whatever_arguments).swap(*this); cannot be simply converted to a free swap function because the constructor does does not bind the the reference argument. You always need a named variable in this case. > A friend-based implementation will allow one to use your type with the > `using std::swap` idiom. ? Marcel
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2024-07-15 20:04 -0700 |
| Message-ID | <v74o0k$13bsj$2@dont-email.me> |
| In reply to | #119626 |
On 07/15/24 11:33 AM, Marcel Mueller wrote:
> Am 28.06.24 um 07:21 schrieb Andrey Tarasevich:
>> Firstly, when implementing a custom `swap` for your custom type it is
>> a better idea to implement it as a friend function
>
> Sometimes it can be useful to have a swap member function.
> E.g. when implementing assignment functions/operators the pattern
> Foo(whatever_arguments).swap(*this);
> cannot be simply converted to a free swap function because the
> constructor does does not bind the the reference argument. You always
> need a named variable in this case.
This is an old and a well-known asymmetry in how overloaded operators
behave in C++. And fixing this asymmetry is actually one of the
side-applications of rvalue references in C++11.
Before C++11 the problem you described could also be observed in the
following example
#include <string>
#include <fstream>
int main()
{
std::string hello = "Hello";
std::ofstream("text.txt") << hello << 123 << std::endl; // 1
std::ofstream("text.txt") << 123 << hello << std::endl; // 2
}
Lines 1 and 2 look very similar. However, line 1 triggers an error
before C++11, while line 2 compiles fine.
`operator <<` for `std::string` is overloaded by a standalone function,
which expects `std::ostream &` (a non-const lvalue reference) as its
first parameter. This immediately means that a temporary object cannot
be used as its argument. For this reason sub-expression
`std::ofstream("text2.txt") << hello` is already invalid.
Meanwhile, line 2 is valid even in C++98. In this case a member overload
of `operator <<` for `int` argument is invoked first. There's no
restrictions on invoking non-const member functions for temporaries.
That invocation returns a `std::ostream &`, which can then be
successfully used as an argument for `operator <<` for `std::string`.
So, in this case the initial `<<` for `int` saves the day as an
accidental "rvalue-to-lvalue" converter.
In C++11 an additional template overload for `<<` has been added to the
library (see [ostream.rvalue])
template <class charT, class traits, class T>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>&& os, const T& x);
which simply does `os << x`, thus taking up the role of rvalue-to-lvalue
converter. Line 1 above becomes valid in C++11.
--
Best regards,
Andrey
[toc] | [prev] | [next] | [standalone]
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
Back to top | Article view | comp.lang.c++
csiph-web