locked
WinRT Namespaces Are::Way::Too::Deep. Has anybody noticed?

    General discussion

  • Using the WinRT namespaces in the header files is very cumbersome when the types are nested way too deep.  I find that the namespace becomes noise.  Since the dreaded using namespace in header files is a big no-no, I propose using a #pragma using directive, applicable to namespaces reflected by the C++/CX syntax to stop qualifying the WinRT types and let the compiler and toolset do it.  For example, in a header file,

    #pragma using Platform

    #pragma using Windows::ApplicationModel

    #pragma using Windows::ApplicationModel::Activation

     

    brings in the types in header file, allowing much shorter member function declarations. Otherwise, can you imagine if you have a member function with four or six parameters and all of them are deeply nested types?

    Sunday, October 9, 2011 8:01 AM

All replies

  • I sympathize, perhaps this will help:

    using Windows::System::VirtualKey;  // Just brings in one symbol

    using namespace Windows::System;  // Brings in lots of symbols

                                                                // EDIT:  These belong only in .cpp files.

    ...

    function( VirtualKey key );

     

    "Note the difference between the using directive and the using declaration : the using declaration allows an individual name to be used without qualification, the using directive allows all the names in a namespace to be used without qualification."

    http://msdn.microsoft.com/en-US/library/aewtdfs3(v=VS.100).aspx

    It would also help if the MSDN documentation actually described the namespace correctly for WinRT under C++.

    http://msdn.microsoft.com/en-us/library/windows/apps/windows.system.virtualkey(v=vs.85).aspx shows:  Namespace     "Windows.System"

    It should be Windows::System

     

     

    • Edited by Andrew7Webb Tuesday, October 25, 2011 5:53 PM Clarify
    Sunday, October 9, 2011 3:27 PM
  • Hi Andrew -

    I filed a documentation bug regarding MSDN showing . instead of :: for the namespace separator in C++.

    There are two general ways to deal with this, as Andrew7Webb states, you can use a 'using namespace' declaration to pull the symbols into your current view (that way you don't need to always qualify) - this is good for .cpp files but is in general a bad practice to do much of in .h files (as you don't know who is including your .h file and having a side-effect of including an .h file resulting in namespace pollution is a bad thing).

    You can also declare namespace aliases to give a bit of shorthand:

    namespace WFC = ::Windows::Foundation::Collections;

    WFC::IVector<int>^ v; //etc

    Friday, October 14, 2011 10:38 PM
  • @Andy,

    To me the issue is that the namespaces unnecessarily clutter the design--why do I need to spend time  in making sure these deeply nested namespaces are correct only to bring in these types?  Let me illustrate a simple class declaration from one of the samples in this site. I will mark the namespace in bold to highlight the unnecessary clutter.  Now, this is one class.  Imagine a large design where multiple namespaces are used by different developers, and each one chooses an alias for the same namespace...you know the drill.  To me this should be "plumbing" offered by the tool for built-in types in the WinRT and a choice to have name resolution if needed--after all the types are not Standard C++ compliant, anyway.

     

    	// FeedData
    	ref class FeedData : public Windows::UI::Xaml::Data::ICustomPropertyProvider, public Platform::IDisposable
        {
        public:
            FeedData();
            void OnPropertyChanged(Platform::String^ propertyName);
             
            // ICustomPropertyProvider interface
            virtual Windows::UI::Xaml::Data::ICustomProperty^ GetCustomProperty(Platform::String^ name);
            virtual Windows::UI::Xaml::Data::ICustomProperty^ GetIndexedProperty(Platform::String^ name, Windows::UI::Xaml::Interop::TypeName typeName);
            virtual Platform::String^ GetStringRepresentation();
            virtual property Windows::UI::Xaml::Interop::TypeName Type { Windows::UI::Xaml::Interop::TypeName get(); }
    
        private:
    		Vector<Object^>^ _items;
            Platform::String^ _title;
    
        public:
    		property Vector<Object^>^ Items { Vector<Object^>^ get();  }
            property Platform::String^ Title { Platform::String^ get(); void set(Platform::String^ value); }
    
            Object^ TitleGetter(Object^ instance);
        };

     

     

    Now, let me do the corresponding using to bring in the types:

    using Platform::IDisposable;
    using Platform::String;

    using Windows::UI::Xaml::Data::ICustomPropertyProvider;
    using Windows::UI::Xaml::Data::ICustomProperty;
    using Windows::UI::Xaml::Interop::TypeName;


    // FeedData ref class FeedData : public ICustomPropertyProvider, public IDisposable { public: FeedData(); void OnPropertyChanged(String^ propertyName); // ICustomPropertyProvider interface virtual ICustomProperty^ GetCustomProperty(String^ name); virtual ICustomProperty^ GetIndexedProperty(String^ name, TypeName typeName); virtual String^ GetStringRepresentation(); virtual property TypeName Type { TypeName get(); } private: Vector<Object^>^ _items; String^ _title; public: property Vector<Object^>^ Items { Vector<Object^>^ get(); } property String^ Title { String^ get(); void set(String^ value); } Object^ TitleGetter(Object^ instance); };

    If you have a fairly large class, the number of using's that have to be done is fairly significant.  To me, this a tool issue--give me the option to have the C++ types brought into the scope of the class without having to declare a using declaration for WinRT types at the very least.  I know that everything can be solved with using statements and aliases, but again, in complex projects with multiple developers it becomes unnecessarily, well, complex.

    Another suggestion is to at least write the using declarations in the samples.  The samples look very daunting and can be greatly simplified.  Let's sell C++ as the language of choice for Metro! ;-)

     

    Which one is easier to sell to the C++ newcomer to Metro?:

     

    ref class FeedData : public Windows::UI::Xaml::Data::ICustomPropertyProvider, public Platform::IDisposable

    or:

    using Windows::UI::Xaml::Data::ICustomPropertyProvider;
    using Platform::IDisposable;

    ref class FeedData : public ICustomPropertyProvider, public IDisposable {...};

    Cheers,

    --Javier

     


    • Edited by ljestrada Tuesday, October 18, 2011 6:22 PM Missing types in using declarations and other corrections
    Tuesday, October 18, 2011 6:11 PM
  • You are using the 'using' declaration to pull single types into your current view - you could be doing a 'using namespace' to pull in entire namespaces for lookup.  This would significantly decrease complexity, at some cost of understanding.  The goal of namespaces is to avoid typename collision - for example, two types in different namespaces that are both called 'Color' but are semantically different types.  They are also useful for organizational purposes; I've often found types I was looking for by using intellisense to explore available namespaces for ones that sound like what I want.

    I'm not sure what the alternative would be - putting everything in the global namespace?  That's similar to the organizational story of the Win32 APIs, and the end result is instead of properly-named types in properly-named namespaces you have very long API names instead.  I don't think there's any real savings of keystrokes to be gained.

    Finally - the decision to use fully::qualified::names within *header* files in samples (instead of using declarations) is because anyone can include a header file, and you don't want the inclusion of a header file to pollute the view of your whole translation unit.  This is a standard C++ coding convention.

    Thursday, October 20, 2011 5:31 PM
  • @andy,

    I'm aware of the using declaration and using directives--ultimately using both in header files are problematic and I have had first-hand experience with both practices.  I'm not sure as to what the alternative is.  I don't want to "unlearn" C++ (C++ Coding Standards, Item 59 by Herb Sutter, I guy I think works at Microsoft ;-) and start using the directive and declaration freely in the header files--I agree that my use is incorrect.

    Regarding aliases as an option, to me the aliases are an alternative but for large projects require coordination between developers to choose the same names.  The other alternative would be to use a namespace that brings in the types, similar to the way the std brings in the C functions or the tr1 types are in the std namespace:

    <span style="white-space:normal"><br/></span>
    
    metro.h
    
    namespace metro
    {
    
      using Platform::IDisposable;
      using Platform::String;
    
      using Windows::UI::Xaml::Data::ICustomPropertyProvider;
      using Windows::UI::Xaml::Data::ICustomProperty;
      using Windows::UI::Xaml::Interop::TypeName;
    } 
    

    and then using them in the header files. It would still need qualification:

     

     

    #include "metro.h"
    
    ref class FeedData : public metro::ICustomPropertyProvider, public metro::IDisposable
    
    {
    public:
      FeedData();
      void OnPropertyChanged(metro::String^ propertyName);
      . . .
    };
    

    But I don't know if this would bring other problems (at the end of the day it seems as a using declaration in disguise and Item 59 of the book aforementioned warns about using declarations at namespace level, which is what I mentioned above).

    Thanks for your time.

     

    Tuesday, October 25, 2011 5:05 PM