Z
Zak
I have some c++ source where construction via
Type var(init); // compiles and...
Type var = init; // does not
I thought the two are supposed to be completely equivalent? Why does
type promotion seem to take place on the first line, but not the
second? Is there a way it can be enabled for the second?
In this case, init is an enum constant contained within Type. The
compiler is g++ 4.x. Both lines work with VS8, unless you turn
language extensions off, in which case you get the g++ behavior.
(error: conversion from ‘TestChc::Choices’ to non-scalar type ‘Test’
requested). Here's the complete code:
#include <iostream>
#include <string>
using namespace std;
#define TWOCHARINT(A, B) (A+(B<<8)) // FIXME: wrong for big endian
archs
template<typename EnumStrucT> struct EnumChoices: EnumStrucT
{EnumChoices(): EnumStrucT() {} // only works if EnumStrucT
default constructs
EnumChoices(const EnumStrucT& arg): EnumStrucT(arg) {}
EnumChoices& operator=(const EnumStrucT& arg)
{this->value = arg.value; return *this;} // ^ EnumStrucT handles
derivations
bool operator== (const EnumStrucT& arg) const
{return this->value.asScalar==arg.value.asScalar;}
bool operator!= (const EnumStrucT& arg) const
{return this->value.asScalar!=arg.value.asScalar;}
const string asString() const
{return string(EnumStrucT::value.asChars, sizeof
EnumStrucT::value.asChars);}
const uint16_t asScalar() const {return EnumStrucT::value;}};
struct TestChc
{enum Choices {CN = 0, C1 = '1', CB = TWOCHARINT('A', 'B'), CS = '
', CZ = 'Z'};
union Value
{uint16_t asScalar;
char asChars[2];
Value(const Choices& arg): asScalar(arg) {}} value;
TestChc(const Choices& arg):value(arg) {}};
typedef EnumChoices<TestChc> Test;
Test& func() {return *(new Test(TestChc::CZ));}
int main (int, char**)
{Test t(TestChc::CB); // , tf('X'); is invalid
// Test t2 = TestChc::CB; // <- this works in VS
Test t2 = func();
// Test t2; // this only works if TestChc default constructs
// Test t2(TestChc::CS);
cout << "size is " << sizeof t2 << endl;
cout << t.asString() << '\t' << t2.asString() << endl;
t = t2;
cout << (t==t2) << endl;
t = TestChc::C1;
cout << (t!=t2) << endl;
return 0;}
There's a little more than needed there, but the crux of the question
is why does the first declaration in main compile while the second (if
uncommented) does not?
Thanks in advance.
Zachary
Type var(init); // compiles and...
Type var = init; // does not
I thought the two are supposed to be completely equivalent? Why does
type promotion seem to take place on the first line, but not the
second? Is there a way it can be enabled for the second?
In this case, init is an enum constant contained within Type. The
compiler is g++ 4.x. Both lines work with VS8, unless you turn
language extensions off, in which case you get the g++ behavior.
(error: conversion from ‘TestChc::Choices’ to non-scalar type ‘Test’
requested). Here's the complete code:
#include <iostream>
#include <string>
using namespace std;
#define TWOCHARINT(A, B) (A+(B<<8)) // FIXME: wrong for big endian
archs
template<typename EnumStrucT> struct EnumChoices: EnumStrucT
{EnumChoices(): EnumStrucT() {} // only works if EnumStrucT
default constructs
EnumChoices(const EnumStrucT& arg): EnumStrucT(arg) {}
EnumChoices& operator=(const EnumStrucT& arg)
{this->value = arg.value; return *this;} // ^ EnumStrucT handles
derivations
bool operator== (const EnumStrucT& arg) const
{return this->value.asScalar==arg.value.asScalar;}
bool operator!= (const EnumStrucT& arg) const
{return this->value.asScalar!=arg.value.asScalar;}
const string asString() const
{return string(EnumStrucT::value.asChars, sizeof
EnumStrucT::value.asChars);}
const uint16_t asScalar() const {return EnumStrucT::value;}};
struct TestChc
{enum Choices {CN = 0, C1 = '1', CB = TWOCHARINT('A', 'B'), CS = '
', CZ = 'Z'};
union Value
{uint16_t asScalar;
char asChars[2];
Value(const Choices& arg): asScalar(arg) {}} value;
TestChc(const Choices& arg):value(arg) {}};
typedef EnumChoices<TestChc> Test;
Test& func() {return *(new Test(TestChc::CZ));}
int main (int, char**)
{Test t(TestChc::CB); // , tf('X'); is invalid
// Test t2 = TestChc::CB; // <- this works in VS
Test t2 = func();
// Test t2; // this only works if TestChc default constructs
// Test t2(TestChc::CS);
cout << "size is " << sizeof t2 << endl;
cout << t.asString() << '\t' << t2.asString() << endl;
t = t2;
cout << (t==t2) << endl;
t = TestChc::C1;
cout << (t!=t2) << endl;
return 0;}
There's a little more than needed there, but the crux of the question
is why does the first declaration in main compile while the second (if
uncommented) does not?
Thanks in advance.
Zachary