Topic: template specializations inside a class
Author: razvanco@gmx.net ("Razvan Cojocaru")
Date: Wed, 5 Mar 2003 21:50:06 +0000 (UTC) Raw View
> As for the rest of what you are saying explicit constructors and
> overloading don't solve this problem.
> A simpler example should demonstrate the problem.
Yes I understand what you want. Interesting enough, while thinking about a
solution I found that this code solves your problem with g++ 3.2:
class A {
public:
template<class X> A(X x);
};
template<> A::A(long l) {}
int main()
{
// int i = 10;
// A ai(i);
long l = 10;
A al(l);
}
The commented code won't compile. Even more interesting, the online Comeau
test not only compiled the commented code, but it even compiled code where
the type of i was float, double, or a user defined type I called X. It would
be interestring to know which compiler is right and why.
The following code also seems to pretty much achieve the desired behaviour,
and this time both compilers agreed that the commented code won't compile:
template<class X> class A;
template<> class A<int>
{
public:
explicit A(int) {}
};
int main()
{
A<int> a(1);
// A<float> a(1);
}
Hope it helps any.
Regards,
Razvan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 6 Mar 2003 00:37:42 +0000 (UTC) Raw View
Razvan Cojocaru wrote:
> It would be interestring to know which compiler is right and why.
Comeau is right. Note that the online Comeau compiler doesn't link.
Had you gone through the link step, you would have seen that the link
failed, becuase the various constructors haven't been defined.
When you do A(int(10)), the compiler will call the A<int> constructor,
whether or not it has seen the definition of it. In order to link, it
must see the definition somewhere, and have the appropriate specialization
generated, but that doesn't have to be everywhere.
Writing an explicit specialization just tells the compiler that the
implementation of that specialization is different. The compiler
doesn't start doing overload resolution against it. (I think, anyway.)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: v_finn@yahoo.com (Vincent Finn)
Date: Fri, 28 Feb 2003 21:38:22 +0000 (UTC) Raw View
Hi,
I have a question about why the standard committee made the following
feature illegal.
It comes from a question in another news group
(microsoft.public.vc.stl) about how to stop a class constructor from
being called due to implicit conversion
what the OP wanted was somthing equivalent to
Prime (explicit unsigned long nValue);
I suggested (code below) specialising the constructor
and making the primary case private
This means that only the explicitly public versions could be used
I was told that this was illegal with references to back it up
So my question is why was it choosen to make this illegal?
i.e. what is dangerous or unwanted about it's behaviour?
Thanks, Vin
class Prime
{
// private constructor
// to stop any types not explicitly wanted
template <typename T> Prime(T);
public:
template <>
Prime (unsigned long nValue)
{
// do stuff
}
template <>
Prime (unsigned short nValue)
{
// do stuff
}
};
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: fvali@eecs.ku.edu (faisal vali)
Date: Mon, 3 Mar 2003 18:52:01 +0000 (UTC) Raw View
Vincent Finn wrote:
>
>
<snip>
> So my question is why was it choosen to make this illegal?
> i.e. what is dangerous or unwanted about it's behaviour?
I used to think that the prohibition of explicit specializations at
class scope was an oversight and that it would be fixed in the next TC -
but after looking at defect report (Issue 44), it seems that the
committee did make a conscious decision to not allow explicit
specializations at class scope. But comments in Issue 44 seem to
indicate that a reversal of this decision is a possibility?? (i think)
anyway - I guess i'd like to know the reason too -
regards,
-fas
>
> Thanks, Vin
>
> class Prime
> {
> // private constructor
> // to stop any types not explicitly wanted
> template <typename T> Prime(T);
>
> public:
> template <>
> Prime (unsigned long nValue)
> {
> // do stuff
> }
>
> template <>
> Prime (unsigned short nValue)
> {
> // do stuff
> }
> };
>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: razvanco@gmx.net ("Razvan Cojocaru")
Date: Mon, 3 Mar 2003 18:52:15 +0000 (UTC) Raw View
Setting aside that you don't put the keyword explicit in the parameter list
but in front of the constructor declaration, I don't really see the logic of
that code.
I don't know why the feature you're asking about is illegal (perhaps you
could point us to the place in the standard where it says it is?) but your
class is not a template and it looks to me like all you need is good ol'
overloading. If you simply don't define any constructors except those you
wrote in the public: section of the class (and perhaps throw in an
'explicit' where necessary), you won't be able to instatiate the class with
parameters that cannot be converted to the constructor parameter types.
Did I missunderstand something?
Regards,
Razvan
"Vincent Finn" <v_finn@yahoo.com> wrote in message
news:3089eb7f.0302280835.47e49a4c@posting.google.com...
> Hi,
>
> I have a question about why the standard committee made the following
> feature illegal.
>
> It comes from a question in another news group
> (microsoft.public.vc.stl) about how to stop a class constructor from
> being called due to implicit conversion
>
> what the OP wanted was somthing equivalent to
> Prime (explicit unsigned long nValue);
>
> I suggested (code below) specialising the constructor
> and making the primary case private
> This means that only the explicitly public versions could be used
> I was told that this was illegal with references to back it up
>
> So my question is why was it choosen to make this illegal?
> i.e. what is dangerous or unwanted about it's behaviour?
>
> Thanks, Vin
>
> class Prime
> {
> // private constructor
> // to stop any types not explicitly wanted
> template <typename T> Prime(T);
>
> public:
> template <>
> Prime (unsigned long nValue)
> {
> // do stuff
> }
>
> template <>
> Prime (unsigned short nValue)
> {
> // do stuff
> }
> };
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: v_finn@yahoo.com (Vincent Finn)
Date: Tue, 4 Mar 2003 16:47:14 +0000 (UTC) Raw View
> Setting aside that you don't put the keyword explicit in the parameter list
> but in front of the constructor declaration,
Don't set this aside. This is the whole point
what was wanted was something equivalent to explicit but in the
parameter list
The code I gave performs that job but is illegal accoding to the
standard
I don't have the reference off-hand but I'll dig out a link
As for the rest of what you are saying explicit constructors and
overloading don't solve this problem.
A simpler example should demonstrate the problem.
My illegal template code will stop the commented line compiling
because the type does not exactly match
Vin
class C
{
public:
explicit C(unsigned long l) {}
};
int main(int argc, char* argv[])
{
unsigned long l = 9;
int i = 8;
C cl(l);
C ci(i); // wants this not to compile
return 0;
}
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: philippe_mori@hotmail.com ("Philippe Mori")
Date: Wed, 5 Mar 2003 02:25:15 +0000 (UTC) Raw View
> Hi,
>
>
> I suggested (code below) specialising the constructor
> and making the primary case private
> This means that only the explicitly public versions could be used
> I was told that this was illegal with references to back it up
>
> So my question is why was it choosen to make this illegal?
> i.e. what is dangerous or unwanted about it's behaviour?
>
> Thanks, Vin
>
> class Prime
> {
> // private constructor
> // to stop any types not explicitly wanted
> template <typename T> Prime(T);
>
> public:
> template <>
> Prime (unsigned long nValue)
> {
> // do stuff
> }
>
> template <>
> Prime (unsigned short nValue)
> {
> // do stuff
> }
> };
>
I think that you can relatively easily achieve what you want
by having only the template version but implement it in a
way that it will compile only for type that you want to
support:
template <typename T>
class PrimeHelper {
private:
// Private and not implemented --- could even be missing.
// The only purpose on this function is for a compilation
// error if we try to uses it (and not a working
// specialization).
unsigned long Convert(T);
};
template < >
class PrimeHelper<unsigned long> {
public:
unsigned long Convert(unsigned long nValue)
{ return nValue; }
};
template < >
class PrimeHelper<unsigned short> {
public:
unsigned short Convert(unsigned short nValue)
{ return nValue; }
};
class Prime
{
public:
template <typename T> Prime(T Value) {
// Possible implementation... --- just a sample
// Will compile only for some PrimeHelper specialization.
m_Value = PrimeHelper<T> Helper().Convert(Value);
}
};
Often when somtehing could not be done directly,
adding an indirection may help to solve the problem.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jhs@edg.com ("John H. Spicer")
Date: Wed, 5 Mar 2003 03:00:37 +0000 (UTC) Raw View
faisal vali wrote:
>
> Vincent Finn wrote:
>
>>
> <snip>
>
>>So my question is why was it choosen to make this illegal?
>>i.e. what is dangerous or unwanted about it's behaviour?
>
>
> I used to think that the prohibition of explicit specializations at
> class scope was an oversight and that it would be fixed in the next TC -
> but after looking at defect report (Issue 44), it seems that the
> committee did make a conscious decision to not allow explicit
> specializations at class scope. But comments in Issue 44 seem to
> indicate that a reversal of this decision is a possibility?? (i think)
> anyway - I guess i'd like to know the reason too -
Many years ago, when the explicit specialization syntax was added to the
language, there was an explicit decision by the committee to permit
specializations only at namespace scope. The wording in the standard that
reflected this decision was not completely clear, and issue 44 was created to
clarify the issue. While discussing issue 44, there was significant interest in
possibly removing this restriction at some point.
In other words, the prohibition was not an oversight, but issue 44 is just a
clarification of the status quo and not an indication of what the committee
might or might not do with respect to changing this rule in the future.
John Spicer
Edison Design Group
>
> regards,
> -fas
>
>
>
>> Thanks, Vin
>>
>>class Prime
>>{
>> // private constructor
>> // to stop any types not explicitly wanted
>> template <typename T> Prime(T);
>>
>> public:
>> template <>
>> Prime (unsigned long nValue)
>> {
>> // do stuff
>> }
>>
>> template <>
>> Prime (unsigned short nValue)
>> {
>> // do stuff
>> }
>>};
>>
>
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]