Sunday, August 7, 2016

Digest for comp.lang.c++@googlegroups.com - 13 updates in 6 topics

Daniel <danielaparker@gmail.com>: Aug 07 02:52PM -0700

Is it safe to do this?
 
 
template <class T>
class A<T>
{
public:
typedef std::pair<const std::string, T> value_type;
 
A(const std::string& key, const T& value)
: data_(key,value)
{
}
 
value_type& data()
{
return reinterpret_cast<value_type&>(data_);
}
 
private:
std::pair<std::string, T> data_;
};
 
int main()
{
A<std::string> a("key","value");
A<std::string>::value_type& data = a.data();
}
 
Thanks,
Daniel
Daniel <danielaparker@gmail.com>: Aug 07 03:10PM -0700

Is it safe to do this?
 
template <class T>
class A
{
public:
typedef std::pair<const std::string, T> value_type;
 
A(const std::string& key, const T& value)
: data_(key,value)
{
}
 
value_type& data()
{
return reinterpret_cast<value_type&>(data_);
}
 
private:
std::pair<std::string, T> data_;
};
 
int main()
{
A<std::string> a("key","value");
A<std::string>::value_type& data = a.data();
}
 
Thanks,
Daniel
"Ahmet Can ÜN" <ahmetcanun@gmail.com>: Aug 07 09:26AM -0700

Hi,
 
 
I wanted to write the content of a std::map to a file. So i wrote
operator<< function for pairs.
 
But i'm getting an error.
#include <string>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <map>
#include <utility>
#include <iterator>
 
using namespace std;
 
template<typename T1, typename T2>
ofstream &operator<<(ofstream &os, pair<T1, T2> rp)
{
return os << " " << rp.first << " " << rp.second << '\n';
}
 
int main()
{
ifstream ifs("salk.txt");
map<string, int> smap;
 
string s;
 
while (ifs >> s)
++smap[s];
 
ofstream ofs("ahmet.txt");
 
copy(smap.begin(),
smap.end(),
ostream_iterator<map<string, int>::value_type>
(ofstream("ahmet.txt")));
return 0;
 
}
 
This is the error message.
 
binary '<<': no operator found which takes a right-hand operand of type
'const std::pair<const _Kty,_Ty>' (or there is no acceptable conversion)
 
When i try to write them to a file without using std::copy, i have no problem. The code below works fine.
 
ofs << make_pair("ahmet can", 3);
"Öö Tiib" <ootiib@hot.ee>: Aug 07 11:22AM -0700

On Sunday, 7 August 2016 19:26:49 UTC+3, Ahmet Can ÜN wrote:
> {
> return os << " " << rp.first << " " << rp.second << '\n';
> }
 
Three problems:
 
1) The ostream reference that those operator<< that you call return is not
convertible to ofstream reference that you return.
 
2) The template is in global namespace but none of its operands is (both
are in namespace std) and so it won't be found by argument dependent
lookup.
 
3) the operator takes a pair by value that may mean some expensive copy
is made while all it needs is const& to pair.

 
That will likely work:
 
namespace std
{
template<typename T1, typename T2>
ostream& operator<<(ostream& os, pair<T1, T2> const& rp)
{
return os << " " << rp.first << " " << rp.second << '\n';
}
}
 
 
> 'const std::pair<const _Kty,_Ty>' (or there is no acceptable conversion)
 
> When i try to write them to a file without using std::copy, i have no problem. The code below works fine.
 
> ofs << make_pair("ahmet can", 3);
 
Are you sure you replaced 'copy()' in *posted* code with that?
I think it can no way compile for reason 1) I gave. What compiler you
use?
"Ahmet Can ÜN" <ahmetcanun@gmail.com>: Aug 07 12:16PM -0700

On Sunday, August 7, 2016 at 9:22:34 PM UTC+3, Öö Tiib wrote:
 
> Are you sure you replaced 'copy()' in *posted* code with that?
> I think it can no way compile for reason 1) I gave. What compiler you
> use?
 
I'm using microsoft visual c++. You are right i changed the return value of
the function before posting it here. Changing the return value to ostream &
was sufficient for this one liner.
 
ofs << make_pair("ahmet can", 3);
 
Why ADL didn't cause a problem for this one. pair is in the std namespace but the operator<< is not.
 
But for the std::copy, as you said i had to put the operator function in to std namespace, then it worked. I thought ADL is not limited to arguments namespace.
 
I wouldn't normally write a function template that takes a pair by value.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Aug 07 04:48PM +0100

Hi,
 
Today I will be creating a new and possibly unique C++ container called
"indexitor".
 
More information to follow.
 
/Flibble
Real Troll <real.troll@trolls.com>: Aug 07 01:50PM -0400

On 07/08/2016 16:48, Mr Flibble wrote:
> called "indexitor".
 
> More information to follow.
 
> /Flibble
 
I am looking forward to this your new invention. What can
I expect to index with this new container?
Bo Persson <bop@gmb.dk>: Aug 07 07:02PM +0200

On 2016-08-07 18:20, Ahmet Can ÜN wrote:
 
> When i try to write them without using std::copy i have no problem. The code
> below works fine.
 
> ofs << make_pair("ahmet can", 3);
 
It's all about name lookup.
 
std::copy, as well as map, pair, string, and ostream_iterator all reside
in namespace std. So that's where the compiler will start looking for an
operator<<. Finding *plenty* of them there, there is no reason to look
in any other namespaces.
 
Especially not the global namespace, where none of the types involved
come from.
 
 
Bo Persson
"Ahmet Can ÜN" <ahmetcanun@gmail.com>: Aug 07 09:20AM -0700

Hi,
 
I wanted to write the content of a std::map to a file. So i wrote
operator<< function for pairs.
 
But i'm getting an error.
#include <string>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <map>
#include <utility>
#include <iterator>
 
using namespace std;
 
template<typename T1, typename T2>
ostream &operator<<(ofstream &os, pair<T1, T2> rp)
{
return os << " " << rp.first << " " << rp.second << '\n';
}
 
int main()
{
 
ifstream ifs("salk.txt");
map<string, int> smap;
 
string s;
 
while (ifs >> s)
++smap[s];
 
ofstream ofs("ahmet.txt");
 
copy(smap.begin(),
smap.end(),
ostream_iterator<map<string, int>::value_type>
(ofstream("ahmet.txt")));
 
return 0;
}
This is the error message.
binary '<<': no operator found which takes a right-hand operand of type
'const std::pair<const _Kty,_Ty>' (or there is no acceptable conversion)
 
When i try to write them without using std::copy i have no problem. The code
below works fine.
 
ofs << make_pair("ahmet can", 3);
fl <rxjwg98@gmail.com>: Aug 07 06:18AM -0700

Hi,
 
When I read the following snippet on move function in a class, I am curious
about:
 
delete ptr;
 
in the move assignment. After this deletion, it assigns a new pointer value:
 
ptr = x.ptr;
 
What is deleted? I see a pointer is deleted, then it assigns a new pointer
value. Could you explain it to me?
 
Thanks,
 
 
class Example6 {
string* ptr;
public:
Example6 (const string& str) : ptr(new string(str)) {}
~Example6 () {delete ptr;}
// move constructor
Example6 (Example6&& x) : ptr(x.ptr) {x.ptr=nullptr;}
// move assignment
Example6& operator= (Example6&& x) {
delete ptr;
ptr = x.ptr;
x.ptr=nullptr;
return *this;
}
// access content:
const string& content() const {return *ptr;}
// addition:
Example6 operator+(const Example6& rhs) {
return Example6(content()+rhs.content());
}
};
Paavo Helde <myfirstname@osa.pri.ee>: Aug 07 04:53PM +0300

On 7.08.2016 16:18, fl wrote:
 
> ptr = x.ptr;
 
> What is deleted? I see a pointer is deleted, then it assigns a new pointer
> value. Could you explain it to me?
 
 
ptr is a pointer to a string. The delete statement deletes not a
pointer, but the thing pointed to, namely the previous string what the
object was holding. Otherwise the previous string would be leaked. The
same is done in the destructor, for example.
 
HTH
Paavo
 
 
"Öö Tiib" <ootiib@hot.ee>: Aug 07 07:18AM -0700

On Sunday, 7 August 2016 16:21:16 UTC+3, fl wrote:
 
> When I read the following snippet on move function in a class, I am curious
> about:
 
> delete ptr;
 
What book you use for learning C++?
Delete expression destructs object(s) previously allocated by the new
expression and releases obtained memory area. The object destructed and
memory area released are pointed at by that 'ptr'.
 
 
> in the move assignment. After this deletion, it assigns a new pointer value:
 
> ptr = x.ptr;
 
Yes since the value of 'ptr' did become invalid (pointing at destructed and
released memory).
 
 
> What is deleted? I see a pointer is deleted, then it assigns a new pointer
> value. Could you explain it to me?
 
If 'ptr' is raw pointer to 'std::string' like it seems to be in code below
then it is awful example. The 'std::string' itself is made to get rid of
ad nauseum management of memory pointed at by raw pointer to 'char' and
already manages everything perfectly what is needed. Doing 'new string'
is inefficient and error-prone manual over-management and bloat of code.
 
> return Example6(content()+rhs.content());
> }
> };
 
Lot shorter cleaner and more efficient that does same:
 
class RealExample6
{
std::string str_;
public:
explicit RealExample6(std::string const& str)
: str_(str)
{}

// access content:
std::string const& content() const {return str_;}
 
// make 'operator+=' as public member and 'operator+' as nonmember
RealExample6& operator+=(RealExample6 const& that)
{
str_ += that.str_;
return *this;
}
};
 
RealExample6 operator+(RealExample6 lhs, Realexample6 const& rhs)
{
return lhs += rhs;
}
fl <rxjwg98@gmail.com>: Aug 07 07:40AM -0700

On Sunday, August 7, 2016 at 9:21:16 AM UTC-4, fl wrote:
> return Example6(content()+rhs.content());
> }
> };
 
Thanks for your replies.
 
I've been learning C++ and using it occasionally. The definitions are not
firmly remembered. I see that there is a namespace line in the original code,
see below please. In this way, it addresses your concern or not?
 
 
 
 
#include <iostream>
#include <string>
using namespace std;
 
class Example6 {
string* ptr;
public:
Example6 (const string& str) : ptr(new string(str)) {}
~Example6 () {delete ptr;}
// move constructor
Example6 (Example6&& x) : ptr(x.ptr) {x.ptr=nullptr;}
// move assignment
Example6& operator= (Example6&& x) {
delete ptr;
ptr = x.ptr;
x.ptr=nullptr;
return *this;
}
// access content:
const string& content() const {return *ptr;}
// addition:
Example6 operator+(const Example6& rhs) {
return Example6(content()+rhs.content());
}
};
 
 
 
Thanks.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: