By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,127 Members | 1,222 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,127 IT Pros & Developers. It's quick & easy.

T t(a) not equivalent to T t = a

P: n/a
I often see it written here that the declaration
T t = a;
(where 'a' is not of type T) calls the copy-constructor and
is exactly equivalent to
T t(( T(a) ));

However the following code gives me a compiler error:

#include <string>

struct M
{
M(std::string const &s);
};

int main()
{
M a ("Hello");
M b = M("Hello");
M c ( M("Hello") );
M d = "Hello";
return 0;
}

m.cc:13: error: conversion from `const char[6]' to non-scalar type `M'
requested

The error is one the "M d" line, and the other lines compiled
correctly. What's going on?

Jul 23 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a

"Old Wolf" <ol*****@inspire.net.nz> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
I often see it written here that the declaration
T t = a;
(where 'a' is not of type T) calls the copy-constructor and
is exactly equivalent to
T t(( T(a) ));

However the following code gives me a compiler error:

#include <string>

struct M
{
M(std::string const &s);
};

int main()
{
M a ("Hello");
M b = M("Hello");
M c ( M("Hello") );
M d = "Hello";
return 0;
}

m.cc:13: error: conversion from `const char[6]' to non-scalar type `M'
requested

The error is one the "M d" line, and the other lines compiled
correctly. What's going on?


M d = std::string("Hello"); // expecting std::string

Implicity convertion to std::string from char* is not allowed, I guess...

Ben
Jul 23 '05 #2

P: n/a
Me
Old Wolf wrote:
I often see it written here that the declaration
T t = a;
(where 'a' is not of type T) calls the copy-constructor and
is exactly equivalent to
T t(( T(a) ));

However the following code gives me a compiler error:

#include <string>

struct M
{
M(std::string const &s);
};

int main()
{
M a ("Hello");
M b = M("Hello");
M c ( M("Hello") );
M d = "Hello";
return 0;
}

m.cc:13: error: conversion from `const char[6]' to non-scalar type `M'
requested

The error is one the "M d" line, and the other lines compiled
correctly. What's going on?


Totally simplified answer: the standard limits up to 2 implicit
conversions to occur. Variable d looks like const char[6] -> const char
* (this one is a freebie so it doesn't really count) -> std::string ->
M.

Jul 23 '05 #3

P: n/a
Old Wolf wrote:
I often see it written here that the declaration
T t = a;
(where 'a' is not of type T) calls the copy-constructor and
is exactly equivalent to
T t(( T(a) ));

However the following code gives me a compiler error:

#include <string>

struct M
{
M(std::string const &s);
};

int main()
{
M a ("Hello");
M b = M("Hello");
M c ( M("Hello") );
M d = "Hello";
return 0;
}

m.cc:13: error: conversion from `const char[6]' to non-scalar type `M'
requested

The error is one the "M d" line, and the other lines compiled
correctly. What's going on?


The problem in line 13 (the last line before the return statement) is
that it requires two user-defined implicit conversions:

const char[6] -> std::string -> M

in order to complete the operation. The C Standard limits user-defined
implicit conversions of a single value to no more than one in any
single expression.

Greg

Jul 23 '05 #4

P: n/a
The error seems very simple, you didn't implement the constructor, but
you have define the constructor explicitly.

Try the following:

struct M
{
M(std::string const &s){};
};

Aries Sun

Jul 23 '05 #5

P: n/a


Aries Sun schreef:
The error seems very simple, you didn't implement the constructor, but
you have define the constructor explicitly.


True, but that doesn't give you a compiler error. Missing definitions
cause linker errors. The OP might link to M.cpp which defines the M
ctor.
The other explanations are correct, though: there is no conversion
from char const* to M.

HTH,
Michiel Salters

Jul 23 '05 #6

P: n/a
Me wrote:
Old Wolf wrote:
I often see it written here that the declaration
T t = a;
(where 'a' is not of type T) calls the copy-constructor and
is exactly equivalent to
T t(( T(a) ));

However the following code gives me a compiler error:

#include <string>

struct M
{
M(std::string const &s);
};

int main()
{
M a ("Hello");
M b = M("Hello");
M c ( M("Hello") );
M d = "Hello";
return 0;
}

m.cc:13: error: conversion from `const char[6]' to non-scalar type `M'
requested

The error is one the "M d" line, and the other lines compiled
correctly. What's going on?


Totally simplified answer: the standard limits up to 2 implicit
conversions to occur. Variable d looks like const char[6] -> const char
* (this one is a freebie so it doesn't really count) -> std::string ->
M.


So why does the "M a" line compile? That has two conversions:
const char[6] -> std::string -> M.

I guess you saying that the ( ) syntax counts as an explicit
conversion but the = syntax does not, even though they are
both initialization?

Jul 23 '05 #7

P: n/a
Me
Old Wolf wrote:
struct M
{
M(std::string const &s);
}; Totally simplified answer: the standard limits up to 2 implicit
conversions to occur. Variable d looks like const char[6] -> const char
* (this one is a freebie so it doesn't really count) -> std::string ->
M.


So why does the "M a" line compile? That has two conversions:
const char[6] -> std::string -> M.


What I meant by the above deals with where the compiler generates its
own temporaries to do the conversion as opposed to the programmer
explicitly creating an unnamed object along the way.
I guess you saying that the ( ) syntax counts as an explicit
conversion but the = syntax does not, even though they are
both initialization?


Greg's answer in this thread was better than mine since he had it in
terms of user defined conversions and mine was just implicit
conversions while not counting the freebies that occur. But if you're
still confused, here is how the compiler might expand these to (I'm
going to use trailing underscores to note the temporaries the compiler
generates):

M a("Hello");
// becomes:
std::string temp_("Hello");
M a(temp_);

M b = M("Hello");
// becomes:
std::string temp_("Hello");
M temp(temp_);
M b(temp);

M c ( M("Hello") );
// becomes:
std::string temp_("Hello");
M temp(temp_);
M c(temp);

M d = "Hello";
// becomes:
std::string temp_("Hello");
M temp__(temp_);
M d(temp__);

M e = std::string("Hello");
// becomes:
std::string temp("Hello");
M temp_(temp);
M e(temp_);

I hope you can see why d doesn't work but the others do.

Jul 23 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.