模板专业化,使用其他模板

时间:2012-10-17 14:55:39

标签: c++ templates specialization

我有问题,我不知道如何正确使用它,但我已经包含了下面的代码。我已经大量删除了代码,因此很容易理解这个问题,但它现在可能无法100%工作,只是为了说明。

问题是模板专业化不起作用。

E.g:

#include <iostream>
#include <swift.hpp>
#include <swift/event.hpp>
#include <swift/event/primitives.tpl>

using namespace swift;

template<class T> void print(const T& value)
{
    std::cout << event::representate(value) << std::endl;
}

int main()
{
    Int32 x = 23;
    print(x);
}

这里的问题是,将打印“〜”。所以event :: representate()在这个例子中指向“swift / event.hpp”中定义的函数,而不是“swift / event / primitives.hpp”中定义的专用函数。

好吧,这不是真正的问题,因为它可以通过将“swift / event.hpp”中的表示函数更改为专门的reprensentate的函数体来轻松解决。

但由于以下原因,我无法做到这一点:

  1. 如果没有std :: stream运算符&lt;&lt;它将不适用于自定义类为自定义类定义(从自由函数开始,尽管可能是这样)。
  2. 不仅需要专业化的event :: representate函数。但也有event :: serialize和event :: deserialize。
  3. 好好看第2点; class OStream在模板化成员函数中使用event :: serialize和event :: deserialize。但是event :: serialize和event :: deserialize 的特化必须能够才能使用OStream(模板)方法。

    那时我已经陷入困境了。我希望有人能指出我正确的方向!

    来源

    swift.hpp:

    #ifndef HG_swift
    #define HG_swift
    
    // C++ Includes
    #include <boost/cstdint.hpp>
    #include <string>
    
    namespace swift
    {
        // Cross-platform primairy types:
        typedef void Void;
        typedef bool Bool;
        typedef Bool Bit;
        typedef char Char;
        typedef unsigned char UChar;
        typedef uint8_t Byte;
        typedef int16_t Int16;
        typedef uint16_t UInt16;
        typedef int32_t Int32;
        typedef uint32_t UInt32;
        typedef Int16 Short;
        typedef UInt16 UShort;
        typedef Int32 Int;
        typedef UInt32 UInt; 
        typedef double Double;
        typedef float Float;
        typedef std::string String;     
    } 
    
    #endif //HG_swift
    

    迅速/ event.hpp

    #ifndef swift_event
    #define swift_event
    
    #include <iostream>
    #include <sstream>
    #include <exception>
    
    #include <swift/String.hpp>
    
    namespace swift
    {   
        class OStream;
        class IStream;
    
        namespace event
        {       
            template<class T> String representate(T& value)
            {
                return "~";
            }
    
            template<class T> void serialize(T& value, OStream& stream) { }
            template<class T> void deserialize(T& value, IStream& stream) { }
        }
    }
    
    #endif //swift_event
    

    迅速/ OStream.hpp:

    #ifndef HG_swift_OStream
    #define HG_swift_OStream
    
    // Imports:
    #include "swift.hpp"
    
    // C++ includes:
    #include <iostream>
    #include <boost/archive/binary_oarchive.hpp>
    
    namespace swift 
    {
        struct OStream
        {
            boost::archive::binary_oarchive archive;
    
            OStream(std::ostream& os) : archive(os, boost::archive::no_header) {}
    
            template<class T> void write(T value)
            {
                event::serialize(value, *this);
            }
        };
    }
    
    #endif //HG_swift_io_OStream
    

    迅速/事件/ primitives.tpl:

    #include <swift.hpp>
    #include <swift/event.hpp>
    //#include <swift/IStream.hpp>
    #include <swift/OStream.hpp>
    #include <iostream>
    #include <sstream>
    
    namespace swift
    {
        // Events
        namespace event
        {
            // Events for primary types:
            // Int32
            template<> String representate<Int32>(Int32& value)
            {
                std::stringstream str;
                str << value;
                return str.str();
            }
    
            template<> void serialize<Int32>(Int32& value, OStream& stream)
            {
                stream.archive & value;
            }
    
            template<> void deserialize<Int32>(Int32& value, IStream& stream)
            {
               stream.archive & value;
            }
    }
    }
    

1 个答案:

答案 0 :(得分:0)

问题是const Int32&无法转换为Int32&。因此专业化无法匹配。更改swift/event/primitives.tpl以使用此功能将起作用:

    template<> String representate<const Int32>(const Int32& value)
    {

或者您可以更改主模板以取const T&而不是T&

对于函数,实际上重载比specialize更好(参见Template Specialization VS Function Overloading):

    String representate(Int32 value)
    {