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

时间:2022-09-13 17:05:09

Well I have a problem, I don't know how to put it properly, but I have included the code below. I have cut alot out of the code so that it is alot easier to understand the problem, but it might not work 100% now, it's just to illustrate.

好吧,我有一个问题,我不知道如何正确,但我已经包括下面的代码。我已经从代码中删除了很多,以便更容易理解问题,但它现在可能不会100%工作,这只是为了说明。

The problem is that the template specialization doesn't work.

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

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);
}

The problem here is, that "~" will be printed. So event::representate() points in this example to the function defined in "swift/event.hpp", and not to the specialized function defined in "swift/event/primitives.hpp".

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

Ok, this isn't really the problem because it could easily been solved by changing the representate function in "swift/event.hpp" to the function body of the specialized reprensentate.

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

But I am not able to do that because of the following to reasons:

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

  1. It won't work with custom classes, if there is not a std::stream operator << defined for the custom class (as of free functions, it could be possible though).
  2. 它不适用于自定义类,如果没有为自定义类定义的std :: stream operator <<(尽管可以使用*函数,但它可能是可行的)。

  3. It is not only the event::representate function that needs specialization. But also event::serialize and event::deserialize.
  4. 它不仅是需要专业化的event :: representate函数。但也有event :: serialize和event :: deserialize。

Well looking at point 2; class OStream uses event::serialize and event::deserialize in a templated member function. But the specialization of event::serialize and event::deserialize must be able to use the OStream (template) methods.

好好看点2; class OStream在模板化成员函数中使用event :: serialize和event :: deserialize。但是event :: serialize和event :: deserialize的特化必须能够使用OStream(模板)方法。

Well I'm stuck at that point. I hope someone could point me in the right direction!

好吧,我坚持到那一点。我希望有人能指出我正确的方向!

Source

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

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

swift/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

swift/event/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 个解决方案

#1


0  

The problem is that a const Int32& cannot be converted to a Int32&. So the specialization cannot be matched. Changing the swift/event/primitives.tpl to use this instead will work:

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

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

or you could change the main template to take a const T& instead of a T&.

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

With functions, it is actually better to overload than specialize (see Template Specialization VS Function Overloading):

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

    String representate(Int32 value)
    {

#1


0  

The problem is that a const Int32& cannot be converted to a Int32&. So the specialization cannot be matched. Changing the swift/event/primitives.tpl to use this instead will work:

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

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

or you could change the main template to take a const T& instead of a T&.

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

With functions, it is actually better to overload than specialize (see Template Specialization VS Function Overloading):

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

    String representate(Int32 value)
    {