0

.hpp

template <typename T>
struct A { virtual A& modify() = 0; };

template <typename T>
struct B : virtual A<T> {};

template <typename T>
struct C : B<T> { C& modify() final; };

.cpp

template <typename T>
C<T>& C<T>::modify() {
    // …
    return *this;
}

// explicit instantiation
template struct C<double>;

I need some methods to return references in order to make “chains” / define an assignment operator / etc.:

C<double> a, b, c;
// …    
a = (b = c).modify();

I also have to deal with virtual inheritance to avoid “the diamond problem” (omitted here for simplicity).

However, this does not work:

MSVC:

Error C2908: explicit specialization; 
'A<T> &C<T>::modify(void)' has already been instantiated

Explicit instantiation works fine w/o virtual inheritance. So I am wondering what is wrong here. (Also everything works fine if there are no member functions returning object references / pointers.)

56th
  • 109
  • 3

1 Answers1

1

The correct syntax for explicit instantiation should be:

template struct C<double>;
         ^^^^^

also, you still need to specify type parameter for your C template:

C<double> a, b, c;
  ^^^^^^

at least g++ and clang accepts this code: http://coliru.stacked-crooked.com/a/23ba6a238a7a17da

but Visual Studio does not...


looks like VS does not like covariant return types, the following compiles under g++/clang and VS but - no covariant return in modified() : http://coliru.stacked-crooked.com/a/70c8e64f0824129a

marcinj
  • 48,511
  • 9
  • 79
  • 100
  • Fixed these misprints, thanx. BTW, MSVC still doesn’t like it as you noticed. – 56th Aug 13 '16 at 18:31
  • @56th I checked this code : http://coliru.stacked-crooked.com/a/70c8e64f0824129a (no covariant return value) with http://webcompiler.cloudapp.net/ and it compiles. – marcinj Aug 13 '16 at 18:53
  • Thank you, but this is still not a solution since one wants to work with the **derived** class reference. “Sliced” object has nothing to do w/ member fields of the derived one, so… – 56th Aug 13 '16 at 19:09
  • @56th I agree, btw. in my tests it appears that original code compiles under VS, once I remove explicit instantition: `template struct C;` – marcinj Aug 13 '16 at 19:12