static_cast, cast operator, and constructors.

Discussion in 'C++' started by Noah Roberts, Jul 18, 2011.

  1. Noah Roberts

    Noah Roberts Guest

    Considder:

    struct ObjectA
    {
    ObjectA(ObjectA const&);

    template < typename T >
    ObjectA(T const&);

    void fun() const;
    };

    struct ObjectB
    {
    operator ObjectA () const;
    };

    static_cast<ObjectA>(an_object_b).fun();

    Which constructor does the standard specify will be called during the
    static_cast: copy or template?

    Behavior I am seeing is that the templated version is called and then
    bases are called on the result of the cast operator.

    Is there a way to explicitly call the cast operator or is that what I'm
    supposedly doing?
    Noah Roberts, Jul 18, 2011
    #1
    1. Advertising

  2. Noah Roberts

    Ian Collins Guest

    On 07/19/11 10:46 AM, Noah Roberts wrote:
    > Considder:
    >
    > struct ObjectA
    > {
    > ObjectA(ObjectA const&);
    >
    > template< typename T>
    > ObjectA(T const&);
    >
    > void fun() const;
    > };
    >
    > struct ObjectB
    > {
    > operator ObjectA () const;
    > };
    >
    > static_cast<ObjectA>(an_object_b).fun();
    >
    > Which constructor does the standard specify will be called during the
    > static_cast: copy or template?


    Is the code complete? The only option is the template.

    > Behavior I am seeing is that the templated version is called and then
    > bases are called on the result of the cast operator.
    >
    > Is there a way to explicitly call the cast operator or is that what I'm
    > supposedly doing?


    Specialise the template constructor for ObjectB.

    template <>
    ObjectA::ObjectA<ObjectB>(ObjectB const&)
    {
    std::cout << "special" << std::endl;
    }

    --
    Ian Collins
    Ian Collins, Jul 19, 2011
    #2
    1. Advertising

  3. Noah Roberts

    Noah Roberts Guest

    On 7/18/2011 4:29 PM, Ian Collins wrote:
    > On 07/19/11 10:46 AM, Noah Roberts wrote:
    >> Considder:
    >>
    >> struct ObjectA
    >> {
    >> ObjectA(ObjectA const&);
    >>
    >> template< typename T>
    >> ObjectA(T const&);
    >>
    >> void fun() const;
    >> };
    >>
    >> struct ObjectB
    >> {
    >> operator ObjectA () const;
    >> };
    >>
    >> static_cast<ObjectA>(an_object_b).fun();
    >>
    >> Which constructor does the standard specify will be called during the
    >> static_cast: copy or template?

    >
    > Is the code complete? The only option is the template.


    No, there's a second option: apply the cast operator and call the copy
    operator with the result.

    >
    >> Behavior I am seeing is that the templated version is called and then
    >> bases are called on the result of the cast operator.
    >>
    >> Is there a way to explicitly call the cast operator or is that what I'm
    >> supposedly doing?

    >
    > Specialise the template constructor for ObjectB.
    >
    > template <>
    > ObjectA::ObjectA<ObjectB>(ObjectB const&)
    > {
    > std::cout << "special" << std::endl;
    > }
    >
    Noah Roberts, Jul 19, 2011
    #3
  4. Noah Roberts

    Ian Collins Guest

    On 07/19/11 11:44 AM, Noah Roberts wrote:
    > On 7/18/2011 4:29 PM, Ian Collins wrote:
    >> On 07/19/11 10:46 AM, Noah Roberts wrote:
    >>> Considder:
    >>>
    >>> struct ObjectA
    >>> {
    >>> ObjectA(ObjectA const&);
    >>>
    >>> template< typename T>
    >>> ObjectA(T const&);
    >>>
    >>> void fun() const;
    >>> };
    >>>
    >>> struct ObjectB
    >>> {
    >>> operator ObjectA () const;
    >>> };
    >>>
    >>> static_cast<ObjectA>(an_object_b).fun();
    >>>
    >>> Which constructor does the standard specify will be called during the
    >>> static_cast: copy or template?

    >>
    >> Is the code complete? The only option is the template.

    >
    > No, there's a second option: apply the cast operator and call the copy
    > operator with the result.


    Your terminology is a little confused. There is a conversion (not cast)
    operator and a copy constructor (not operator).

    The sequence you describe required two levels of conversion, the
    template constructor one.

    Assignment or omitting the template constructor should call the
    conversion operator:

    ObjectA a = an_object_b;

    --
    Ian Collins
    Ian Collins, Jul 19, 2011
    #4
  5. Noah Roberts

    Jorgen Grahn Guest

    On Mon, 2011-07-18, Ian Collins wrote:
    > On 07/19/11 11:44 AM, Noah Roberts wrote:
    >> On 7/18/2011 4:29 PM, Ian Collins wrote:
    >>> On 07/19/11 10:46 AM, Noah Roberts wrote:
    >>>> Considder:
    >>>>
    >>>> struct ObjectA
    >>>> {

    ....

    >> No, there's a second option: apply the cast operator and call the copy
    >> operator with the result.

    >
    > Your terminology is a little confused. There is a conversion (not cast)
    > operator and a copy constructor (not operator).


    And I personally get confused by a class called "ObjectA". It's a
    class, not an object.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
    Jorgen Grahn, Jul 19, 2011
    #5
  6. Noah Roberts

    Noah Roberts Guest

    On 7/19/2011 6:12 AM, Jorgen Grahn wrote:
    > On Mon, 2011-07-18, Ian Collins wrote:
    >> On 07/19/11 11:44 AM, Noah Roberts wrote:
    >>> On 7/18/2011 4:29 PM, Ian Collins wrote:
    >>>> On 07/19/11 10:46 AM, Noah Roberts wrote:
    >>>>> Considder:
    >>>>>
    >>>>> struct ObjectA
    >>>>> {

    > ...
    >
    >>> No, there's a second option: apply the cast operator and call the copy
    >>> operator with the result.

    >>
    >> Your terminology is a little confused. There is a conversion (not cast)
    >> operator and a copy constructor (not operator).

    >
    > And I personally get confused by a class called "ObjectA". It's a
    > class, not an object.


    You guys get worked up over some pretty weird shit.
    Noah Roberts, Jul 19, 2011
    #6
  7. Noah Roberts

    Jorgen Grahn Guest

    On Tue, 2011-07-19, Noah Roberts wrote:
    > On 7/19/2011 6:12 AM, Jorgen Grahn wrote:
    >> On Mon, 2011-07-18, Ian Collins wrote:
    >>> On 07/19/11 11:44 AM, Noah Roberts wrote:
    >>>> On 7/18/2011 4:29 PM, Ian Collins wrote:
    >>>>> On 07/19/11 10:46 AM, Noah Roberts wrote:
    >>>>>> Considder:
    >>>>>>
    >>>>>> struct ObjectA
    >>>>>> {

    >> ...
    >>
    >>>> No, there's a second option: apply the cast operator and call the copy
    >>>> operator with the result.
    >>>
    >>> Your terminology is a little confused. There is a conversion (not cast)
    >>> operator and a copy constructor (not operator).

    >>
    >> And I personally get confused by a class called "ObjectA". It's a
    >> class, not an object.

    >
    > You guys get worked up over some pretty weird shit.


    I wasn't worked up. But surely you want your postings to be as clear as
    possible?

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
    Jorgen Grahn, Jul 20, 2011
    #7
  8. Noah Roberts

    James Kanze Guest

    On Jul 18, 11:46 pm, Noah Roberts <> wrote:
    > Considder:


    > struct ObjectA
    > {
    > ObjectA(ObjectA const&);


    > template < typename T >
    > ObjectA(T const&);


    > void fun() const;
    > };
    >
    > struct ObjectB
    > {
    > operator ObjectA () const;
    > };


    > static_cast<ObjectA>(an_object_b).fun();


    > Which constructor does the standard specify will be called during the
    > static_cast: copy or template?


    My first reaction is that it's ambiguous. In both cases
    (supposing "an_object_b" has type ObjectB), you need a const
    conversion, followed by a user defined conversion. There is
    a rule that all other things being equal, a non-template will
    have precedence over a template, but I'm not sure it applies
    here. And there are all sorts of subtilities involving overload
    resolution in the presence of const; I don't have a copy of the
    standard here to try to work them out.

    > Behavior I am seeing is that the templated version is called and then
    > bases are called on the result of the cast operator.


    > Is there a way to explicitly call the cast operator or is that what I'm
    > supposedly doing?


    There's no way of explicitly calling either the conversion
    operator or the constructor; the only way either gets called is
    because of a conversion (explicit or implicit). My feeling is
    that either the conversion is ambiguous, or perhaps the
    conversion operator should be called, because of the
    non-template over template rule; but without having a copy of
    the standard to verify it by, I wouldn't want to swear on it.

    --
    James Kanze
    James Kanze, Jul 20, 2011
    #8
    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. Dave Rahardja

    static_cast versus C-style type cast

    Dave Rahardja, Aug 18, 2003, in forum: C++
    Replies:
    1
    Views:
    509
    Rolf Magnus
    Aug 18, 2003
  2. Alexander Stippler

    static_cast vs. C-stype cast

    Alexander Stippler, Dec 8, 2003, in forum: C++
    Replies:
    2
    Views:
    643
    Hendrik Schober
    Dec 10, 2003
  3. Kobe
    Replies:
    3
    Views:
    542
    Tomás
    Feb 15, 2006
  4. Bo Peng
    Replies:
    11
    Views:
    1,061
    Victor Bazarov
    Oct 20, 2006
  5. junyangzou
    Replies:
    13
    Views:
    246
Loading...

Share This Page