Specalizing question

This is a discussion on Specalizing question within the C++ Programming forums, part of the General Programming Boards category; Is it possible to achieve something like this: Code: template<typename StrT> struct InputTraits { }; template<> struct InputTraits<const wchar_t*> { ...

  1. #1
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,455

    Specalizing question

    Is it possible to achieve something like this:
    Code:
    	template<typename StrT> struct InputTraits { };
    	template<> struct InputTraits<const wchar_t*>
    	{
    		static decltype(std::wcout) & OutStream;
    		static decltype(std::wcin) & InStream;
    	};
    	template<> decltype(std::wcout) & InputTraits<const wchar_t*>::OutStream = std::wcout;
    	template<> decltype(std::wcin) & InputTraits<const wchar_t*>::InStream = std::wcin;
    ...Somehow, some way? I figured that depending on if the type T is const wchar_t* or const char* or some other type such as std::string or std::wstring, I could make a struct which contains a reference to the standard input and output for that particular type.

    Of course, this just spits back errors at me.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,668
    Looks fine to me (not an expert at c++0x, tho). Wikipedia does mention: "Microsoft's Visual C++ 2010 compiler provides a decltype operator that closely mimics the semantics as described in the standards committee proposal". Doesn't sound too encouraging, IMO.



    ITSA
    Socket Library!

  3. #3
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,455
    No, I think you're missing the point. The decltype is not the problem. The problem is that I cannot specialize the structure properly. The compiler barfs at the initializing of the reference members:
    error C2998: 'cannot be a template definition'
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,668
    Quote Originally Posted by Elysia View Post
    No, I think you're missing the point. The decltype is not the problem. The problem is that I cannot specialize the structure properly. The compiler barfs at the initializing of the reference members:
    error C2998: 'cannot be a template definition'
    Well...this works:

    Code:
        template<typename StrT> struct InputTraits { };
        template<> struct InputTraits<const char*>
        {
            static ostream & OutStream;
            static istream & InStream;
        };
        template<> ostream & InputTraits<const char*>::OutStream = std::cout;
        template<> istream & InputTraits<const char*>::InStream = std::cin;
        
        int main(void)
        {
            InputTraits<const char*>::OutStream << "Howdy!" << endl;
        }
    ...almost identical, except for the decltype bit.

    Does this compile?

    Code:
        template<typename StrT> struct InputTraits { };
        template<> struct InputTraits<const wchar_t*>
        {
            typedef decltype(std::wcout) OutStreamT;
            typedef decltype(std::wcin) InStreamT;
            static OutStreamT & OutStream;
            static InStreamT & InStream;
        };
        template<> InputTraits<const wchar_t*>::OutStreamT & InputTraits<const wchar_t*>::OutStream = std::wcout;
        template<> InputTraits<const wchar_t*>::InStreamT & InputTraits<const wchar_t*>::InStream = std::wcin;



    ITSA
    Socket Library!

  5. #5
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,455
    Nope.
    Error 1 error C2998: 'Input::InputTraits<const wchar_t*>::OutStreamT &Input::InputTraits<wchar_t const *>::OutStream' : cannot be a template definition g:\application data2\visual studio 2008\projects\temp\temp3.cpp 139
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,668
    Quote Originally Posted by Elysia View Post
    Nope.
    Error 1 error C2998: 'Input::InputTraits<const wchar_t*>::OutStreamT &Input::InputTraits<wchar_t const *>::OutStream' : cannot be a template definition g:\application data2\visual studio 2008\projects\temp\temp3.cpp 139
    Okay, what about this?

    Code:
        template<typename StrT> struct InputTraits { };
        template<> struct InputTraits<const wchar_t*>
        {
            typedef std::wostream OutStreamT;
            typedef std::wistream InStreamT;
            static OutStreamT & OutStream;
            static InStreamT & InStream;
        };
        template<> InputTraits<const wchar_t*>::OutStreamT & InputTraits<const wchar_t*>::OutStream = std::wcout;
        template<> InputTraits<const wchar_t*>::InStreamT & InputTraits<const wchar_t*>::InStream = std::wcin;



    ITSA
    Socket Library!

  7. #7
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,455
    Nope. For the record, this doesn't work either:
    Code:
        template<typename StrT> struct InputTraits { };
        template<> struct InputTraits<const wchar_t*>
        {
            typedef std::wostream OutStreamT;
            typedef std::wistream InStreamT;
            static OutStreamT & OutStream;
            static InStreamT & InStream;
        };
        template<> std::wostream & InputTraits<const wchar_t*>::OutStream = std::wcout;
        template<> std::wistream & InputTraits<const wchar_t*>::InStream = std::wcin;
    EDIT: Comeau says:
    Code:
    Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
    Copyright 1988-2008 Comeau Computing.  All rights reserved.
    MODE:strict errors C++ C++0x_extensions
    
    "ComeauTest.c", line 11: error: 
              "std::wostream &InputTraits<const wchar_t *>::OutStream" is not an
              entity that can be explicitly specialized
          template<> std::wostream & InputTraits<const wchar_t*>::OutStream = std::wcout;
                                                                  ^
    
    "ComeauTest.c", line 12: error: 
              "std::wistream &InputTraits<const wchar_t *>::InStream" is not an
              entity that can be explicitly specialized
          template<> std::wistream & InputTraits<const wchar_t*>::InStream = std::wcin;
                                                                  ^
    
    2 errors detected in the compilation of "ComeauTest.c".
    Last edited by Elysia; 06-10-2010 at 01:29 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,668
    Quote Originally Posted by Elysia View Post
    Nope. For the record, this doesn't work either:
    Code:
        template<typename StrT> struct InputTraits { };
        template<> struct InputTraits<const wchar_t*>
        {
            typedef std::wostream OutStreamT;
            typedef std::wistream InStreamT;
            static OutStreamT & OutStream;
            static InStreamT & InStream;
        };
        template<> std::wostream & InputTraits<const wchar_t*>::OutStream = std::wcout;
        template<> std::wistream & InputTraits<const wchar_t*>::InStream = std::wcin;
    EDIT: Comeau says:
    Code:
    Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
    Copyright 1988-2008 Comeau Computing.  All rights reserved.
    MODE:strict errors C++ C++0x_extensions
    
    "ComeauTest.c", line 11: error: 
              "std::wostream &InputTraits<const wchar_t *>::OutStream" is not an
              entity that can be explicitly specialized
          template<> std::wostream & InputTraits<const wchar_t*>::OutStream = std::wcout;
                                                                  ^
    
    "ComeauTest.c", line 12: error: 
              "std::wistream &InputTraits<const wchar_t *>::InStream" is not an
              entity that can be explicitly specialized
          template<> std::wistream & InputTraits<const wchar_t*>::InStream = std::wcin;
                                                                  ^
    
    2 errors detected in the compilation of "ComeauTest.c".
    Huh. Apparently, C++0X has some new rules...

    Code:
    #include <iostream>
    template<typename StrT> struct InputTraits { };
    template<> struct InputTraits<const wchar_t*>
    {
        static decltype(std::wcout) & OutStream;
        static decltype(std::wcin) & InStream;
    };
    decltype(std::wcout) & InputTraits<const wchar_t*>::OutStream = std::wcout;
    decltype(std::wcin) & InputTraits<const wchar_t*>::InStream = std::wcin;
    In other words, just remove the "template<>" in the initialization of static members of fully specialized classes...
    Last edited by Sebastiani; 06-10-2010 at 02:04 PM.



    ITSA
    Socket Library!

  9. #9
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,455
    Huh...
    Well, it's a shame I went ahead without it then. I finished it:
    Code:
    #include <boost/format.hpp>
    #include <iostream>
    #include <string>
    #include <sstream>
    
    namespace Input
    {
    	template<typename StrT> void StreamOut(const StrT& Output) { std::wcout << Output; }
    	void StreamOut(const char* Output) { std::cout << Output; }
    	void StreamOut(const std::string& Output) { std::cout << Output; }
    	template<typename T> void StreamOut(const boost::basic_format<T>& Output) { StreamOut(Output.str()); }
    
    	template<typename StrT, typename T> bool StreamIn(StrT& Stream, T& Buffer)
    	{
    		std::wstring Answer;
    		std::getline(Stream, Answer);
    		std::wstringstream StrStream(Answer);
    		return (StrStream >> Buffer) != nullptr;
    	}
    
    	template<typename T> bool StreamIn(T& Buffer) { return StreamIn(std::wcin, Buffer); }
    
    	template<typename DataT, typename StrT1, typename StrT2, typename StrT3, typename Validator>
    	void Read(DataT& Out, const StrT1& Question, const StrT2& ErrorType, const StrT3& ErrorValidation, Validator ValidatorFnc)
    	{
    		for (;;)
    		{
    			StreamOut(Question);
    			if (!StreamIn(Out))
    			{
    				StreamOut(ErrorType);
    				continue;
    			}
    			if (ValidatorFnc(Out))
    				break;	
    			StreamOut(ErrorValidation);
    		}
    	}
    }
    
    int main()
    {
    	int x;
    	const int Max = 20;
    	const int Min = 10;
    
    	Input::Read
    	(
    		x,
    		L"Enter an integer: ",
    		L"That is not a valid integer. Try again.\n",
    		boost::wformat(L"Invalid input. The integer must be bigger than %d and lower than %d.\n") % Min % Max,
    		[Min, Max](int Value) { return Value >= Min && Value <= Max; }
    	);
    	std::cout << "You entered: " << x << std::endl;
    }
    I must say: this is beautiful. Wonderful. Excellent. Super.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A question about a question
    By hausburn in forum C++ Programming
    Replies: 3
    Last Post: 04-25-2010, 05:24 AM
  2. Alice....
    By Lurker in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 06-20-2005, 02:51 PM
  3. Debugging question
    By o_0 in forum C Programming
    Replies: 9
    Last Post: 10-10-2004, 05:51 PM
  4. Question...
    By TechWins in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 07-28-2003, 09:47 PM
  5. Question, question!
    By oskilian in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 12-24-2001, 12:47 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21