none
Explicit interface implementation #2

    Question

  • There arised another question:
    When I have two interfaces with the same function names, and I want to use explicit interface implementation
    for these functions, the following code generates errors (only) when TestClass is a class template. Why?

    interface class I1  
    {
        void f();  
    };  
     
    interface class I2  
    {  
        void f();  
    };  
     
    template<class T> 
    ref class TestClass : I1, I2  
    {  
    public:  
        virtual void f() = I1::f, I2::f {}      //Generates errors  
    }; 

    I have to replace the implementation by

    template<class T> 
    ref class TestClass : I1, I2  
    {  
    public:  
        virtual void f1() = I1::f {}  
        virtual void f2() = I2::f {}  
    };  
     

    In my case, the problem is that I have two interfaces and a combined version
    interface class IGet  
    {  
        property int default[int] {  
            int get(int);  
        }  
    };  
     
    interface class ISet  
    {  
        property int default[int] {  
            void set(int, int);  
        }  
    };  
     
    interface class IGetSet : IGet, ISet  
    {  
        property int default[int] {  
            int get(int);  
            void set(int, int);  
        }  
    }; 

    I have to redeclare the default property in the IGetSet interface (I get an compiler error else when
    trying to use the default property of IGetSet - I don't know why you can't simply combine the get and set properties...)

    Thank you in advance
    Alex
    Friday, January 02, 2009 9:54 AM

All replies

  • I don't know for sure, but I suspect that this is because your suggested code would result in 2 identically named methods f() and the template mechanism wouldn't know how to cope with that, nor would the compiler know what you meant if you called TestClass::f().
    Friday, January 02, 2009 12:16 PM
  • The curious thing is that the code works without the template.
    This is exactly what was done in the second example in the
    Visual C++ help: http://msdn.microsoft.com/en-us/library/fw0bbh51.aspx

    My problem is that I have two interfaces which have the same
    property - one only with a get member and the other only with
    a set member; and then there is a combined interface which
    should share both. When I try instead

    interface class IGetSet: IGet, ISet {};  
     
    IGetSet^ val = ...;  
     
    val[4] = 5;     // the compiler complains that IGet has no  
                    // default::set 

    there is an compiler error.
    But in my eyes it does not make sense to implement the same function
    for IGet::default::get and IGetSet::default::get two times.

    Alex
    Friday, January 02, 2009 1:26 PM
  • I don't get the problem.  This sample code compiled and ran without issue:

    #include "stdafx.h"

    using namespace System;

    generic <typename T>
    interface class IGet 

      property T default[int] { 
        T get(int); 
      } 
    }; 

    generic <typename T>
    interface class ISet 

      property T default[int] { 
        void set(int, T); 
      } 
    }; 

    generic <typename T>
    interface class IGetSet : IGet<T>, ISet<T>

      property T default[int] { 
        T get(int); 
        void set(int, T); 
      } 
    };

    template<typename T>
    ref class TestClass : IGetSet<T>

      array<T>^ mValues;
    public:
      TestClass(int size) { mValues = gcnew array<T>(size); }
      property T default[int] {
        virtual T get(int index) { return mValues[index]; }
        virtual void set(int index, T value) { mValues[index] = value; }
      }
    };

    int main(array<System::String ^> ^args)
    {
      TestClass<int>^ test = gcnew TestClass<int>(10);
      ISet<int>^ setter = test;
      setter[0] = 42;
      IGet<int>^ getter = test;
      Console::WriteLine(getter[0]);
      Console::ReadLine();
      return 0;
    }


    Hans Passant.
    Friday, January 02, 2009 3:39 PM
    Moderator
  • I did not try it with generics (perhaps it would be working with it), but I
    need specialization which is not supported there (as far as I know).
    There is also no problem when the member functions have the same
    name as in the interface...

    The problem occurs, when I want to use

    template<typename T>   
    ref class TestClass : IGetSet<int>, IGetSet<double>, IGetSet<String^>, ...  
    {  
     
    };  
     

    There are many default properties with different return types,
    and therefore explicit implementation is necessary.

    Alex
    Friday, January 02, 2009 5:41 PM
  • I don't have a clue what you're trying to do.  I suspect the iceberg that's going to sink that Titanic is the notion of having more than one default property.
    Hans Passant.
    Friday, January 02, 2009 6:47 PM
    Moderator
  • What I want to do is:
    I have an (self defined) array of unknown type (that will be defined at runtime)
    and a function which works on double arrays.

    MyArray<int> arr(10);    //MyArray is derived of AsArray<int>,AsArray<double>,...
    arr[5] = 23;
     
    fn(arr);
     
    //Somewhere else:
     
    void fn(AsArray<double>^ dArr)
    {
        double d = dArr[5];
        ...
    }

    Alex
    Friday, January 02, 2009 9:32 PM