Tech Off Thread

8 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

C++ member function templates

Back to Forum: Tech Off
  • User profile image
    cravikiran

    Hi,

    I have a class with a templatized member function:

    class Serializer
    {
        // ...

        template <class T> void serialize(const T& value);
    };

    Now, I want to specialize for a particular type.  It seems that there are a few ways to do this (maybe this is wrong?).  One is to create a regular overload like so:

    void serialize(const SerializableObject*& value);

    Supposedly this will get preference when matching over specific template instantiations but it doesn't seem to be the case (it results in a non-existant template instatiation for SerializableObject* to be created anyway and since I don't have an explicit instantiation for that, it results in unresolved linker errors).

    So, I thought I would go with the explicit instantiation approach.  Now, perhaps I am getting syntax wrong here but when I put this line in the header file with the class declaration, I get an internal compiler error in VC7.1:

    template<> void serialize<SerializableObject*>(const SerializableObject*& value);

    produces

    fatal error C1001: INTERNAL COMPILER ERROR
            (compiler file 'msc1.cpp', line 2701) 

    Without declaring in the header, I don't think I can do any explicity instantiation in the C++ file either.

    Am I doing something wrong or is this a bug in VC (and is there a workaround if it is)?

    Thanks,
    Ravi Chodavarapu

  • User profile image
    Sven Groot

    Could you post a compilable (or, well, complete since it isn't compilable anyway) example demonstrating the problem?

  • User profile image
    cravikiran

    Sven,

    Well, I have sort of moved on past it but for fun, here is something that would produce the ICE:

    // someheader.h, include from some cpp
    class SomeObject {};
    class Demonstration
    {
        template <class T> void foo(const T& value);
        template <> void foo(const SomeObject*& value);
    };

    If you do definitions in the header, the ICE disappears but another error:

    class SomeObject {};
    class Demonstration
    {
        template <class T> void foo(const T& value) {}
        template <> void foo(const SomeObject*& value) {}
    };

    Making it the following will fix the problem:

    class SomeObject {};
    class Demonstration
    {
        template <class T> void foo(const T& value) {}
        template <> void foo(const SomeObject& value) {}
    };

    (Removing consts also fixes it). Thinking about it afterwards, I'm still not entirely sure but I think it's something like: const SomeObject*& can actually be used to change the pointer (even though that pointer cannot be used to change the SomeObject).  This is contrary to what the const T& guarantees - it requires that you shouldn't be able to modify the pointer with the reference.



  • User profile image
    Sven Groot

    class SomeObject {};
    
    class Demonstration
    {
        template <class T> void foo(const T& value) { }
        template <> void foo(const SomeObject*& value) { }
    };

    There are two issues with this code, one is what causes the error, the other isn't caught by VC.

    The issue that causes this code to fail to compile is this: template <> void foo(const SomeObject*& value); has a signature that doesn't correspond to the template, so it isn't a valid specialization. The template wants a const reference, and you'd think that your specialization has a signature specifying "const reference to a pointer", but due to the (sometimes insane) order in which declarations are read in C++, the actual signature is "reference to a const pointer" which doesn't match the template.

    There is a second issue here: specializations are not allowed inside class definitions. VC does allow them there, but Comeau does not. So just fixing the definition makes the code work on VC, but still not entirely up to spec with the ISO standard. This bit may also have something to do with why VC2005 still gives an ICE with the declarations-only version.

    So the following code is a completely correct version, which compiles fine in VC2003, VC2005, and Comeau 4.3.3:
    class SomeObject {};
    
    class Demonstration
    {
        template <class T> void foo(const T& value) { }
    };
    
    template <> void foo(SomeObject* const & value) { }


    There is still the matter of the ICE. You never want a compiler to give an ICE on any input, ideally. VC (both 2003 and 2005) give an Internal Compiler Error when these two conditions are both met: 1. the function specialization is inside the class definition and 2. the specialisation has no method body. The ICE still occurs if the method body is defined elsewhere.

    I will file an issue against VC2005 on this matter.

  • User profile image
    Sven Groot
  • User profile image
    Sven Groot

    Response from the VC team:

    Microsoft wrote:
    Hi: I've confirmed that this issue still occurs with the latest build of the compiler.

    Unfortunately we are finished making changes to the compiler for the Visual C++ 2005 release so we won't be able to fix as part of this release. But we will
    take another look at this issue for the next release of Visual C++.

    Thanks for reporting the issue.

    Jonathan Caves
    Visual C++ Compiler Team

  • User profile image
    cravikiran

    Thanks for following up on the issue Sven.

  • User profile image
    tomault

    Sven Groot wrote:
    Response from the VC team:
    Microsoft wrote:Hi: I've confirmed that this issue still occurs with the latest build of the compiler.

    Unfortunately we are finished making changes to the compiler for the Visual C++ 2005 release so we won't be able to fix as part of this release. But we will
    take another look at this issue for the next release of Visual C++.

    Thanks for reporting the issue.

    Jonathan Caves
    Visual C++ Compiler Team


    Could Microsoft pleasepleaseplease distribute bugfixes for the compiler more often than once every two years?

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.