locked
Template method in WinRT class

    Question

  • Hello, 

    I have the following class(excerpt):

    public ref class BindableBase: Windows::UI::Xaml::DependencyObject, 
                Windows::UI::Xaml::Data::INotifyPropertyChanged, 
                Windows::UI::Xaml::Data::ICustomPropertyProvider
            {
     protected private:
                template<typename T, typename U>
                bool setProperty(T& storage, U&& newValue, Platform::String^ name)
                {
                    if(storage == newValue)
                        return false;
                    storage = newValue;
                    OnPropertyChanged(name);
                    return true;
                }

    If I try to set property which type is another WinRT class( name it OtherRTClass) I have the following compilation error:
    error C3987: 'setProperty': signature of public member contains native type 'ns:: OtherRTClass ^&'

    Why I have such a error with protected private visibility? How to fix it?

    If I change signature of my setProperty method to 

    template<typename T>

    bool setProperty(T storage, T newValue, Platform::String^name)                  

    then compilation goes ok but I have linker error:

    error LNK2022: metadata operation failed (80131187) : Inconsistent method declarations in duplicated types (... methods: setProperty< ns:: OtherRTClass ^>): (0x06000008).
    error LNK2022: metadata operation failed (801311D6) : Differing number of methods in duplicated types (...): (0x02000004)

    So the question is: how to fix my errors or how to use template methods with WinRT if I'm doing it wrong.






    • Edited by ixSci Tuesday, July 23, 2013 7:50 AM
    Tuesday, July 23, 2013 7:47 AM

Answers

  • Hi,ixSci

    I can't reappear your issue,can you give me the entire code?

    I have try my best to do it,and below is my code:

    namespace MyTemplateField{
    	public ref class MyTemplate sealed:Windows::UI::Xaml::DependencyObject{
    	protected private:
    		template<typename T,typename U>
    		bool setProperty(T storage,U newvalue,Platform::String^ name){
    			if(storage==newvalue)
    				return false;
    			else  return true;
    		}
    	public:
    		MyTemplate(){
    			Platform::String^ s("aa");
    			setProperty<int,int>(10,10,s);
    		}
    	};
    }

    I compiled it without any issue,as you say ,our questions concentrate upon the template,and I don't kown

    the meaning of &&,so I just write it as my habit.

    Wednesday, July 24, 2013 5:47 AM
    Moderator

All replies

  • A ref class is not allowed to have native members above "private", so even "protected" or "protected private" is too open. The error message is misleading. Alternatively, you can use "internal". However, this makes the method visible to everything inside the current assembly.

    I remember those linker errors. Have you tried a rebuild? At least that was necessary for me.


    Tuesday, July 23, 2013 11:39 AM
  • Hi,ixSci

    I can't reappear your issue,can you give me the entire code?

    I have try my best to do it,and below is my code:

    namespace MyTemplateField{
    	public ref class MyTemplate sealed:Windows::UI::Xaml::DependencyObject{
    	protected private:
    		template<typename T,typename U>
    		bool setProperty(T storage,U newvalue,Platform::String^ name){
    			if(storage==newvalue)
    				return false;
    			else  return true;
    		}
    	public:
    		MyTemplate(){
    			Platform::String^ s("aa");
    			setProperty<int,int>(10,10,s);
    		}
    	};
    }

    I compiled it without any issue,as you say ,our questions concentrate upon the template,and I don't kown

    the meaning of &&,so I just write it as my habit.

    Wednesday, July 24, 2013 5:47 AM
    Moderator
  • A ref class is not allowed to have native members above "private", so even "protected" or "protected private" is too open. The error message is misleading. Alternatively, you can use "internal". However, this makes the method visible to everything inside the current assembly.

    As far as I understand docs it is not true. internal just like plain C++ public but doesn't affect metadata, as well as private protected(or vice versa) is like protected but without metadata affection. So visibility should be fine. It doesn't work with internal either.

    I remember those linker errors. Have you tried a rebuild? At least that was necessary for me.

    Tried Clean build and Rebuild - nothing helps.
    Wednesday, July 24, 2013 7:30 AM
  • Hi James, please try Platform::String^ instead of int as the function args. Also do not include explicit template argument types when invoke function, compiler infers it automatically.
    Thursday, July 25, 2013 6:02 AM
  • Hi,ixSci

    Platform::String^ s("aa");
    			Platform::String^ m("bb");
    			Platform::String^ n("cc");
    			setProperty<Platform::String^,Platform::String^>(m,n,s);

    I just change the int to Platform::String^,it run ok yet.but i can't understand what's your meaning of "don't explicit template argument types when invoke function",just setProperty<Platform::String^,Platform::String^>?

    Can you tell me how do it as you say?

    Thanks.


    Friday, July 26, 2013 8:50 AM
    Moderator
  • What compiler do you use? 

    Platform::String^ m("bb");
    Platform::String^ n("cc");
    setProperty(m,n,s);

    Friday, July 26, 2013 1:11 PM
  • hi,ixSci

    I use VS 2012

    Tuesday, July 30, 2013 1:17 AM
    Moderator
  • Hi,ixSci

    any update?

    Wednesday, July 31, 2013 1:20 AM
    Moderator
  • I don't understand it doesn't work with November CTP compiler, will check it when VS2013 RTM available
    Thursday, August 01, 2013 7:44 AM
  • Hi,ixSci

    If you get it please sharing your solutions & experience here. It will be very beneficial for other community members who have similar questions.And I will change this thread as a discuss one after 4 days or you agree me in 4 days.

    Best regard!

    Thursday, August 01, 2013 10:00 AM
    Moderator