Topic: The ages-old question: is this code correct?


Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/12/06
Raw View
[my own message and code snipped]
Greg Comeau <comeau@panix.com> wrote in message
news:81af61$s2r$1@panix.com...
> I don't see how the above code could possible work.  By eye, I see
> at least three errors (MyCombo is not defined, f is private,
> and the specialization doesn't look right).  Given this,
> I think it's fair to ask you to post the actual code again.
>
> Even at that though, I cannot imagine us (Comeau C++) compiling
> anything similar, at least not in "strict ANSI mode" of Comeau C++.
> Please check the version of Comeau C++ you are running, and with
what
> _options_ you are invoking it.

I'm sorry Greg, I posted erroneus code. I apologize for that. The code
accepted by your compiler is the one that's correct by the Standard,
and it is:

template <class A> struct Combo
{
    template <class B> static void f(B& b)
    {
    }
};

template <> template <class B> void Combo<int>::f(B& b)
{
}

int main()
{
    typedef Combo<char> MyCombo;
    int x(9);
    MyCombo::f(x);
}


This code is, to the best of my knowledge, correct by the Standard
(please tell me whether this is correct), and is compilable by Comeau
C++ without any flags. This feature is important to me as I see
important practical uses of it.


Andrei




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: comeau@panix.com (Greg Comeau)
Date: 1999/12/07
Raw View
In article <s4me2k9qeg129@news.supernews.com> "Andrei Alexandrescu" <andrewalex@hotmail.com> writes:
>Greg Comeau <comeau@panix.com> wrote in message
>news:81af61$s2r$1@panix.com...
>> I don't see how the above code could possible work.  By eye, I see
>> at least three errors (MyCombo is not defined, f is private,
>> and the specialization doesn't look right).  Given this,
>> I think it's fair to ask you to post the actual code again.
>I'm sorry Greg, I posted erroneus code. I apologize for that. The code
>accepted by your compiler is the one that's correct by the Standard,
>and it is:
>
>template <class A> struct Combo
>{
>    template <class B> static void f(B& b)
>    {
>    }
>};
>
>template <> template <class B> void Combo<int>::f(B& b)
>{
>}
>
>int main()
>{
>    typedef Combo<char> MyCombo;
>    int x(9);
>    MyCombo::f(x);
>}
>
>This code is, to the best of my knowledge, correct by the Standard
>(please tell me whether this is correct), and is compilable by Comeau
>C++ without any flags.

Well, let's see... MyCombo is now defined, you use struct instead of class,
so f is now public, and you use template<> for proper specialization,
so it looks right to me now.

>This feature is important to me as I see
>important practical uses of it.

Yep, templates sure are great :)

- Greg
--
       Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
          Producers of Comeau C/C++ 4.2.42 -- NOTE 4.2.42 NOW AVAILABLE
    Email: comeau@comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
                *** WEB: http://www.comeaucomputing.com ***
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: comeau@panix.com (Greg Comeau)
Date: 1999/11/23
Raw View
In article <s3dol5b3ef66@news.supernews.com> "Andrei Alexandrescu" <andrewalex@hotmail.com> writes:
>
>My intent is to write a specialized version for a member function in a
>template class. The tweak is that the function is a template function.
>
>I tried this, but MWCW didn't accept the code. Comeau C++ accepted it.
>Who's right?
>
>
>template <class A> class Combo
>{
>    template <class B> static void f(B& b)
>    {
>    }
>};
>
>template <class B> void Combo<int>::f(B& b)
>{
>}
>
>int main()
>{
>    int x(9);
>    MyCombo::f(x);
>}

I don't see how the above code could possible work.  By eye, I see
at least three errors (MyCombo is not defined, f is private,
and the specialization doesn't look right).  Given this,
I think it's fair to ask you to post the actual code again.

Even at that though, I cannot imagine us (Comeau C++) compiling
anything similar, at least not in "strict ANSI mode" of Comeau C++.
Please check the version of Comeau C++ you are running, and with what
_options_ you are invoking it.

- Greg
--
       Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
          Producers of Comeau C/C++ 4.2.42 -- NOTE 4.2.42 NOW AVAILABLE
    Email: comeau@comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
                *** WEB: http://www.comeaucomputing.com ***
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jbarfurth@vossnet.de (Joerg Barfurth)
Date: 1999/11/21
Raw View
Andrei Alexandrescu <andrewalex@hotmail.com> wrote:

> My intent is to write a specialized version for a member function in a
> template class. The tweak is that the function is a template function.
>
> I tried this, but MWCW didn't accept the code. Comeau C++ accepted it.
> Who's right?
Without seeing MWCW's error message, I cannot tell if it was right for
the wrong reason (which I suspect, as many current compilers just cannot
handle this kind of template code).

Comeau probably supports the old way of specializing (without
template<>). But by the words of the standard your program seems to be
ill-formed and should not be accepted.

> template <class A> class Combo
> {
>     template <class B> static void f(B& b)
>     {
>     }
> };

template<>  // IMO you need that here
> template <class B> void Combo<int>::f(B& b)
> {
> }

// With my addition it looks perfectly legal.

> int main()
> {
>     int x(9);
>     MyCombo::f(x);
I assume you meant Combo<int>::f(x) or left out a typedef Combo<int>
MyCombo. As posted no compiler should accept your code.

> }
>
>
> Andrei

-- J   rg


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/11/21
Raw View
James Kuyper Jr. <kuyper@wizard.net> wrote in message
news:3836F573.739786B0@wizard.net...
> >     template <class B> static void f(B& b)
> >     {
> >     }
> > };
> >
> > template <class B> void Combo<int>::f(B& b)
> > {
> > }
> >
> > int main()
> > {
> >     int x(9);
> >     MyCombo::f(x);
> > }
>
> Are you sure this is exactly the same code that Comeau C++ accepted?
> You've no definition of MyCombo anywhere.

Sorry. main() is predated by:

typedef Combo<char> MyCombo;


Andrei




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Ian McCulloch" <ipm105@rsphy1.anu.edu.au>
Date: 1999/11/22
Raw View
Andrei Alexandrescu wrote in message ...
>
>My intent is to write a specialized version for a member function in a
>template class. The tweak is that the function is a template function.
>
>I tried this, but MWCW didn't accept the code. Comeau C++ accepted it.
>Who's right?
>
>
>template <class A> class Combo
>{
>    template <class B> static void f(B& b)
>    {
>    }
>};
>
>template <class B> void Combo<int>::f(B& b)
>{
>}

Do you need template<> here?  ie

template <>
template <class B> void Combo<int>::f(B& b) { }

After inserting this, and assuming that "typedef Combo<int> MyCombo" was
accidentally missing from your post, it compiled fine on Digital CXX.
Without the template<>, it spits it back.

>
>int main()
>{
>    int x(9);
>    MyCombo::f(x);
>}
>
>Andrei


Ian
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Gene Bushuyev" <gbush@my-deja.com>
Date: 1999/11/22
Raw View
Andrei Alexandrescu <andrewalex@hotmail.com> wrote in message
news:s3dol5b3ef66@news.supernews.com...
>
> My intent is to write a specialized version for a member function in a
> template class. The tweak is that the function is a template function.
>
> I tried this, but MWCW didn't accept the code. Comeau C++ accepted it.
> Who's right?
>
>
> template <class A> class Combo
> {
>     template <class B> static void f(B& b)
>     {
>     }
> };
>
> template <class B> void Combo<int>::f(B& b)
> {
> }
>

The above specialization is obviously incorrect, since it's lacking
template<>. But the question is even more difficult: is explicit
specialization allowed for a template class template member without explicit
specialization of a template member of that template class and without
explicit specialization of the whole template class? And similar question is
whether explicit specialization of a template member is allowed without
explicit specialization of the template class.
In your particular case the solution is pretty simple: explicitly specialize
the whole template class. E.g.

template <>
class Combo<int>
{
  public:
  template<class B> static void f(B& b){}
};

int main()
{
     int x(9);
    Combo<int>::f(x); // calls specialized version
}

The code above compiles and runs as expected in BCB4.

I guess this one also should work:

template<class A> template<> void Combo<A>::f(int&){}

but my compiler complains: "Specialization within template classes not yet
implemented" Is it actually a legal code?

Gene Bushuyev
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "J.Barfurth" <techview@bfk-net.de>
Date: 1999/11/22
Raw View

Gene Bushuyev <gbush@my-deja.com> schrieb in im Newsbeitrag:
07a3139460615b9CPIMSSMTPE01@msn.com...
> Andrei Alexandrescu <andrewalex@hotmail.com> wrote in message
> news:s3dol5b3ef66@news.supernews.com...
> >
> > My intent is to write a specialized version for a member function in a
> > template class. The tweak is that the function is a template function.

Gene suggests:
    template<>
> > template <class B> void Combo<int>::f(B& b)
> > {
> > }
AFAIK this one is legal.

> The above specialization is obviously incorrect, since it's lacking
> template<>. But the question is even more difficult: is explicit
> specialization allowed for a template class template member without explicit
> specialization of a template member of that template class and without
> explicit specialization of the whole template class? And similar question is
This one I don't understand. What do you mean ?

> whether explicit specialization of a template member is allowed without
> explicit specialization of the template class.
AFAIK this one is not allowed

> In your particular case the solution is pretty simple: explicitly specialize
> the whole template class. E.g.
I don't think you need that. And what if the template class contains more
members ? You'd have to define them all again.

> I guess this one also should work:
>
> template<class A> template<> void Combo<A>::f(int&){}
> but my compiler complains: "Specialization within template classes not yet
> implemented" Is it actually a legal code?

I guess not. AFAIK you have to specialize from left to right:
    template <class T> class A {
        template <class U> class B {
            template <class V> class C{
                template <class W> void foo(T,U,V,W);
            };
        };
    };
    template<class T>template<class U>template<class V>template<class W>
    void A<T>::B<U>::C<V>::foo(T,U,V,W) { /*...*/ }// general definition

    template<>template<class U>template<class V>template<class W>
    void A<int>::B<U>::C<V>::foo(int,U,V,W) { /*...*/ }// specialize (1)

    template<>template<>template<class V>template<class W>
    void A<int>::B<long>::C<V>::foo(int,long,V,W) { /*...*/ }// specialize
(2)

    template<>template<>template<>template<class W>
    void A<int>::B<long>::C<double>::foo(int,long,double,W) { /*...*/ }//
specialize (3)

    template<>template<>template<>template<>
    void A<int>::B<long>::C<double>::foo<char>(int,long,double,char)
 /*...*/ }// specialize (4)

It may well be that, after such a specialization is declared, you are not
allowed to specialize the whole class any more.
    template<>template<> class A<int>::B<long> { /*...*/};    // illegal
after line specialize (2) ?

I'm not sure whether the standard allows it the other way around, IF you
declare the specializations in the class template definition (MSVC6 (!!)
does- you have to define them inside the class definition as well though):
It would look like (if it is indeed allowed)
    template <class T>
    class X {
        template <class U> void bar(U);
        template<> void bar<int>(int);
    };
    template <class T>template<class U> void X<T>::bar(U) { /*...*/ };
    template <class T> void X<T>::bar<int>(int) { /*...*/ };    // not sure
about the syntax here

I dont have my copy of the standard here. I'll try to post the relevant
references when I get back.

If I'm completely off, could someone please correct me. I stumbled across
the relevant paragraphs lately, but I can only hope I didn't put things
upside down here.

-- J   rg Barfurth




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/11/20
Raw View
My intent is to write a specialized version for a member function in a
template class. The tweak is that the function is a template function.

I tried this, but MWCW didn't accept the code. Comeau C++ accepted it.
Who's right?


template <class A> class Combo
{
    template <class B> static void f(B& b)
    {
    }
};

template <class B> void Combo<int>::f(B& b)
{
}

int main()
{
    int x(9);
    MyCombo::f(x);
}


Andrei




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/11/20
Raw View
Andrei Alexandrescu wrote:
>
> My intent is to write a specialized version for a member function in a
> template class. The tweak is that the function is a template function.

My understanding is that template member functions of class templates
are legal, but very rarely supported. Several of the standard's template
classes require such functions.

> I tried this, but MWCW didn't accept the code. Comeau C++ accepted it.
> Who's right?
>
> template <class A> class Combo
> {
>     template <class B> static void f(B& b)
>     {
>     }
> };
>
> template <class B> void Combo<int>::f(B& b)
> {
> }
>
> int main()
> {
>     int x(9);
>     MyCombo::f(x);
> }

Are you sure this is exactly the same code that Comeau C++ accepted?
You've no definition of MyCombo anywhere. Assuming that MyCombo is a
typo for Combo, your use of it in main() has no explicit template
argument, no default for that argument, and no way for the compiler to
deduce the argument.

For this type of question, it's generally a good idea to post the exact
text of the code that didn't compile, and of the error messages
produced.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]