template<typename T>
struct Foo {
int m_val;
void swap(Foo& ano) {
Foo tmp(ano);
ano.m_val=m_val;
m_val=tmp.m_val;
};
}
template<typename T>
struct Foo {
int m_val;
void swap(Foo& ano) {
Foo tmp(ano);
ano.m_val=m_val;
m_val=tmp.m_val;
};
}
How to implement Foo:swap(..) if m_val is enum type or function pointer type? (not using std::swap)
On Thu, 2024-06-27 at 14:02 -0700, red floyd wrote:
On 6/27/2024 10:42 AM, wij wrote:
template<typename T>
struct Foo {
int m_val;
void swap(Foo& ano) {
Foo tmp(ano);
ano.m_val=m_val;
m_val=tmp.m_val;
};
}
How to implement Foo:swap(..) if m_val is enum type or function pointer type?
(not using std::swap)
Exactly the same way. Why wouldn't you? And why wouldn't you use
std::swap internally? Or is this homework?
To be specific, how to implement the swap specialization for enum type and function pointer type (including class member function type)?
template<typename T> void swap(T&, T&) {/* omitted */}; // primiary template
template<> void swap(..) // specialization ????
On Thu, 2024-06-27 at 14:02 -0700, red floyd wrote:
On 6/27/2024 10:42 AM, wij wrote:
template<typename T>
struct Foo {
int m_val;
void swap(Foo& ano) {
Foo tmp(ano);
ano.m_val=m_val;
m_val=tmp.m_val;
};
}
How to implement Foo:swap(..) if m_val is enum type or function pointer type?
(not using std::swap)
Exactly the same way. Why wouldn't you? And why wouldn't you use
std::swap internally? Or is this homework?
To be specific, how to implement the swap specialization for enum type and function pointer type (including class member function type)?
template<typename T> void swap(T&, T&) {/* omitted */}; // primiary template
template<> void swap(..) // specialization ????
template<typename T>
struct Foo {
int m_val;
void swap(Foo& ano) {
Foo tmp(ano);
ano.m_val=m_val;
m_val=tmp.m_val;
};
}
How to implement Foo:swap(..) if m_val is enum type or function pointer type? (not using std::swap)
Am 28.06.2024 um 07:21 schrieb Andrey Tarasevich:
On 06/27/24 10:42 AM, wij wrote:
template<typename T>
struct Foo {
int m_val;
void swap(Foo& ano) {
Foo tmp(ano);
ano.m_val=m_val;
m_val=tmp.m_val;
};
}
How to implement Foo:swap(..) if m_val is enum type or function
pointer type?
(not using std::swap)
Firstly, when implementing a custom `swap` for your custom type it is
a better idea to implement it as a friend function
m_val is public anyway, so there's no need for a friend.
template<typename T> struct Foo
{
int m_val;
friend void swap(Foo &lhs, Foo &rhs) noexcept
{
int t = lhs.m_val;
lhs.m_val = rhs.m_val;
rhs.m_val = t;
}
};
A friend-based implementation will allow one to use your type with the
`using std::swap` idiom.
On Thu, 2024-06-27 at 14:02 -0700, red floyd wrote:
On 6/27/2024 10:42 AM, wij wrote:
template<typename T>
struct Foo {
int m_val;
void swap(Foo& ano) {
Foo tmp(ano);
ano.m_val=m_val;
m_val=tmp.m_val;
};
}
How to implement Foo:swap(..) if m_val is enum type or function pointer type?
(not using std::swap)
Exactly the same way. Why wouldn't you? And why wouldn't you use
std::swap internally? Or is this homework?
To be specific, how to implement the swap specialization for enum type and function pointer type (including class member function type)?
template<typename T> void swap(T&, T&) {/* omitted */}; // primiary template
template<> void swap(..) // specialization ????
Am 28.06.2024 um 18:33 schrieb Andrey Tarasevich:
Yes, there kinda-sorta is a "need for a friend", if you take into
account the fact that the OP is actually defining a class _template_
`Foo<T>. There's no visible reason why `Foo` is a template in the OP's
code snippet, but if they want a template - so be it.
friend is unnecessary or you want to make a swap from a Foo
with a different type to be a friend to another Foo's type.
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.
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;
}
Without :: before swap this doesn't work.
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.
My own swap is called; I've tried that in the debugger.
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.
I've shown the syntax.
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.
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
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.
Firstly, when implementing a custom `swap` for your custom type it is a better idea to implement it as a friend function
A friend-based implementation will allow one to use your type with the
`using std::swap` idiom.
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.
On 07/15/24 11:33 AM, Marcel Mueller wrote:
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);
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.
Am 16.07.24 um 05:04 schrieb Andrey Tarasevich:
On 07/15/24 11:33 AM, Marcel Mueller wrote:
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);
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.
But is it really a good idea to have
swap(X&, X&&)
and
swap(X&&, X&)
?
I am not sure.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 491 |
Nodes: | 16 (2 / 14) |
Uptime: | 117:48:22 |
Calls: | 9,686 |
Calls today: | 2 |
Files: | 13,728 |
Messages: | 6,176,335 |