help-gplusplus
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Is it valid to call 'operator T()' directly in an template function?


From: Jan Rendek
Subject: Re: Is it valid to call 'operator T()' directly in an template function?
Date: Mon, 03 Jan 2005 15:29:48 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.4) Gecko/20030630

Feng Ye wrote:
Hi,
  I got this error when compiling the following code by g++ 3.4.3.

  error: 'const class Field' has no member named 'operator T'

  The comeau online c++ reports no error. Is it a bug of g++?

Regards,
Feng Ye

=====================8<===========================
class Field
{
public:
    operator int() const { return *(int*)value; }
    operator char*() const { return (char*)value; }

private:
    void* value;
};

template<class T>
class Test
{
public:
    void setValue(int){}
    void setValue(char*){}

    void fromField(const Field& f);
};

template<class T>
void Test<T>::fromField(const Field& f)
{
    setValue( f.operator T() );
}

int main()
{
    Field f;
    Test<int> t;

    t.fromField(f);
}

Hello,
There has been a lot of changes, indeed, in template handling from gcc
3.3 to gcc 3.4
Main change is that template declaration are now analysed. Before that,
they only had to be syntactically correct. Only the instanciation of
the template was analysed.
Now, considering your code, I'd say the compiler is correct. There is
no 'operator T' in your class Field. What can the 'f.operator T()' refer
to ?
Of course with the previous versions of gcc. This question is never
raised. I did not check the standard, but I feel this behavior is
consistent.

<OT>
What this codes tries to emulate is template partial specialization.
Your class Field knows how to deal with 'int' or 'char *' but does
not know how to handle the generic case.
A way (please correct me if I'm wrong here) to handle this
would be :

-----------------------------------------------------------------
class Field
{
public:
  template <class T> operator T() const; // Generic case conversion
                                         // defined, but not declared

private:
  void* value;
};

// int specialization
template <>
Field::operator int() const {return *(int*)value; }

// char specialization
template <>
Field::operator char*() const {return (char*)value; }


template<class T>
class Test
{
public:
  void setValue(T){} // This now can be generic
  void fromField(const Field& f);
};

template<class T>
void Test<T>::fromField(const Field& f)
{
  setValue( f.operator T() ); // Ok since operator T() now exists
}

int main()
{
  Field f;
  Test<int> t;
  t.fromField(f);
}
-----------------------------------------------------------------

Of course much better solutions exists for that kind of problems,
using type traits for instance. But that a bit off topics.
</OT>

Regards,

Jan Rendek
--
r e n d e k @ l o r i a . f r

Attachment: pgpWc5ElI5KRh.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]