問題があります。適切に配置する方法がわかりませんが、以下のコードを含めました。問題を理解しやすくするためにコードを大幅に省略しましたが、現在は 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の関数本体に変更することで簡単に解決できたので、これは実際には問題ではありません。
しかし、次の理由により、それを行うことができません。
- std::stream 演算子 << がカスタム クラスに対して定義されていない場合、カスタム クラスでは機能しません (ただし、フリー関数の場合は可能です)。
- 特殊化が必要なのは 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;
}
}
}