Re: Template explicit specialization

Discussion in 'C++' started by Francesco, Jan 29, 2011.

  1. Francesco

    Francesco Guest

    On 28 Gen, 17:14, CornedBee <> wrote:
    > On Jan 28, 8:07 am, Francesco <> wrote:
    >
    > > Hi to all,

    >
    > > in light of what is written in 14.7.3.6/7 of the standard (template
    > > explicit specialization), could you please confirm (or reject) my
    > > understanding of the following code?
    > > My understanding is that the code is ill-formed because Foobar uses
    > > the non specialized FirstFunc template (through SecondFunc) just
    > > before FirstFunc is specialized for the same data type ( double ).

    >
    > Correct. Of course, no diagnostic is required, so in effect the
    > program is just undefined.


    Got it.

    >
    > > Other than this, is the code fine? More specifically:
    > > - is the call chain for the int type well-formed (taking into account
    > > the initial forward declaration and the specialization)?

    >
    > Yes.


    Great.

    [ Snip stuff ]

    >
    > If one translation unit contains a specialization that is used in
    > another, the code is ill-formed, NDR.
    > If two translation units contain specializations for the same type,
    > the ODR is violated. This is irrespective of whether the two
    > specializations are identical or not.


    Can you please elaborate more? See below… (*1*)

    >
    > Generally speaking, a few rules can make the mental effort required
    > much smaller:
    > 1) Don't specialize function templates. Overload the functions
    > instead.


    Got it. But I'm using the specializations as an extension mechanism,
    they're defined after the main template function that uses them. So in
    case of simple overloading they're not called. But I get your point (I
    think).

    > 2) Put declarations (and when possible, definitions) for all
    > specializations directly after the primary template. (Unless of course
    > that's impossible, which is the case when you use explicit
    > specialization of a class template as an extension mechanism.)


    Same as above, but I got the point.

    >
    > Sebastian
    >


    First of all thanks for the reply. I would really appreciate a little
    bit more on what you wrote above, marked as (*1*).
    Consider please the code below (include guards are omitted to shorten
    up).
    I would think that if you take UnitOne and UnitTwo by themselves they
    should be ok.
    That is:
    - UnitOne should call the specialized version for int and the default
    for double.
    - UnitTwo should call both specialized versions.
    If I understood well what you wrote, you're saying that this program
    as a whole (linked) is totally ill-formed because:
    1. UnitOne calls DoSome( double ) WITHOUT having available a
    specialization that is present in another unit?
    2. Both units include the int specialization and so this would break
    the ODR, even if they're the same?

    This would break my heart… ;-)
    Can you please confirm or reject the above and point me to the
    relevant sections in the standard, please?

    Thanks in advance,
    Francesco


    //------------------------------------------------------------
    // Default.h
    // this is meant to be specialized
    template< typename T >
    void DoSomeAux( T const & ) {}
    // this is not meant to be specialized
    template< typename T >
    void DoSome( T const & inObj )
    {
    DoSomeAux( inObj );
    }

    //------------------------------------------------------------
    // SpecialInt.h
    #include "Default.h"
    template< >
    void DoSomeAux< int >( int const & ) {}

    //------------------------------------------------------------
    // SpecialDouble.h
    #include "Default.h"
    template< >
    void DoSomeAux< double >( double const & ) {}

    //------------------------------------------------------------
    // UnitOne.cpp
    #include "SpecialInt.h"
    void Some()
    {
    DoSome( 1 );
    DoSome( 1.1 );
    }

    //------------------------------------------------------------
    // UnitTwo.cpp
    #include "SpecialInt.h"
    #include "SpecialDouble.h"
    void SomeOther()
    {
    DoSome( 1 );
    DoSome( 1.1 );
    }


    --
    [ comp.std.c++ is moderated. To submit articles, try posting with your ]
    [ newsreader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    Francesco, Jan 29, 2011
    #1
    1. Advertising

  2. Francesco Wrote:

    > I would think that if you take UnitOne and UnitTwo by themselves
    > they should be ok.
    > That is:
    > - UnitOne should call the specialized version for int and the
    > default for double.
    > - UnitTwo should call both specialized versions.
    > If I understood well what you wrote, you're saying that this
    > program as a whole (linked) is totally ill-formed
    > because:
    > 1. UnitOne calls DoSome( double ) WITHOUT having available
    > a specialization that is present in another unit?


    That is right.

    > 2. Both units include the int specialization and so this would
    > break the ODR, even if they're the same?


    Yes, because the specialisations are not declared inline.

    >
    > This would break my heartÂ… ;-)
    > Can you please confirm or reject the above and point me to
    > the relevant sections in the standard, please?


    I don't have a coipy of the standard available here, so I can't give you an
    exact quote or a section number.
    However, what yopu should remember is that a specialisation of a template
    (either explicit or implicit) is a regular class or function.
    The only special case is that an implicit specialisation of a function
    template acts as an inline function, even if there was no such specification
    on the template.

    Given that a specialisation is a regular function, 1 causes an ODR
    violation, because the program contains two functions with the same name and
    signature, but with different implementations and not all of them inline.
    2 causes an ODR violation, because the program contains two non-inline
    definitions of the same function.

    >
    > Thanks in
    > advance,
    > Francesco
    >

    Bart v Ingen Schenau


    --
    [ comp.std.c++ is moderated. To submit articles, try posting with your ]
    [ newsreader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    Bart van Ingen Schenau, Jan 30, 2011
    #2
    1. Advertising

  3. Francesco

    Francesco Guest

    Thanks to all for the replies.
    After your input I reviewed a little bit the standard and I guess
    these are the relevant parts:

    14.7:5
    — an explicit specialization shall be defined at most once in a
    program (according to 3.2)
    14.7.3:5
    If a template, a member template or the member of a class template is
    explicitly specialized then that specialization shall be declared
    before the first use of that specialization that would cause an
    implicit instantiation to take place, in every translation unit in
    which such a use occurs; no diagnostic is required.
    14.7.3:13
    An explicit specialization of a function template is inline only if it
    is explicitly declared to be, and independently of whether its
    function template is.

    So summarizing, if I use the specializations as an "extension
    mechanism" (I cannot declare them right after the main template) I
    must:
    - be sure that the declaration of a specialization appears BEFORE ANY
    use I make of that specialization
    - I must define them only once (the linker would complain about
    duplicate symbols)
    - If I want the specialization as inline I must explicitly define it
    so
    - If I use inline specializations I must not define many of them with
    different implementations (the linker would not complain, but ODR
    would be violated)

    The last three point are actually the usual behavior with non-template
    functions…

    Hope I'm getting it right.
    Thanks a lot,
    Francesco


    --
    [ comp.std.c++ is moderated. To submit articles, try posting with your ]
    [ newsreader. If that fails, use mailto: ]
    [ --- Please see the FAQ before posting. --- ]
    [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
     
    Francesco, Jan 30, 2011
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. J.T. Conklin
    Replies:
    1
    Views:
    468
    David Hilsee
    Aug 11, 2004
  2. Patrick Kowalzick
    Replies:
    0
    Views:
    853
    Patrick Kowalzick
    Oct 29, 2004
  3. Andy
    Replies:
    5
    Views:
    527
    Shezan Baig
    Jan 30, 2005
  4. stain
    Replies:
    3
    Views:
    970
    stain
    May 30, 2006
  5. Barry
    Replies:
    2
    Views:
    374
    Barry
    Sep 30, 2007
Loading...

Share This Page