0

問題があります。適切に配置する方法がわかりませんが、以下のコードを含めました。問題を理解しやすくするためにコードを大幅に省略しましたが、現在は 100% は機能しない可能性があります。説明のためだけです。

問題は、テンプレートの特殊化が機能しないことです。

例えば:

#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/primitives.hpp」で定義された特殊な関数ではなく、「swift/event.hpp」で定義された関数を指しています。

「swift/event.hpp」のrepresentate関数を特殊なrepresentateの関数本体に変更することで簡単に解決できたので、これは実際には問題ではありません。

しかし、次の理由により、それを行うことができません。

  1. std::stream 演算子 << がカスタム クラスに対して定義されていない場合、カスタム クラスでは機能しません (ただし、フリー関数の場合は可能です)。
  2. 特殊化が必要なのは event::representate 関数だけではありません。しかし、event::serialize と event::deserialize も同様です。

ポイント2をよく見てください。クラス OStream は、テンプレート化されたメンバー関数で event::serialize および event::deserialize を使用します。ただし、event::serialize および event:: deserialize の特殊化では、OStream (テンプレート) メソッドを使用できる必要があります。

さて、私はその時点で立ち往生しています。誰かが私を正しい方向に向けてくれることを願っています!

ソース

スウィフト.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

スウィフト/イベント/プリミティブ.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;
        }
}
}
4

1 に答える 1

0

問題は、 をconst Int32&に変換できないことInt32&です。したがって、専門分野は一致しません。swift/event/primitives.tpl代わりにこれを使用するように変更すると機能します。

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

または、メイン テンプレートを変更して、 のconst T&代わりに を使用することもできますT&

関数では、実際には特化するよりもオーバーロードする方が適切です (テンプレートの特殊化 VS 関数のオーバーロードを参照)。

    String representate(Int32 value)
    {
于 2012-10-17T15:13:12.147 に答える