C++ 操作员<&书信电报;智能指针的重载

C++ 操作员<&书信电报;智能指针的重载,c++,visual-studio-2010,c++11,template-meta-programming,typetraits,C++,Visual Studio 2010,C++11,Template Meta Programming,Typetraits,我想重载操作符如果(我使用的是C++03名称空间),您可以使用第一个解决方案enable\u): 模板 类是\u funky:public boost::false\u type{}; 模板 类是\u funky:public boost::true\u type{}; 模板 typename boost::enable_if:type 操作员一些选项,请参见第二个live at 给定 #包括 #包括 使用名称空间std; 模板结构foo{ 虚拟FoO和操作符可能是你把自己置身于一个糟糕的竞技场

我想重载操作符如果(我使用的是C++03名称空间),您可以使用第一个解决方案
enable\u):

模板
类是\u funky:public boost::false\u type{};
模板
类是\u funky:public boost::true\u type{};
模板
typename boost::enable_if:type

操作员一些选项,请参见第二个live at

给定

#包括
#包括
使用名称空间std;
模板结构foo{

虚拟FoO和操作符

可能是你把自己置身于一个糟糕的竞技场,使C++看起来像java。 C++指针、值和引用是不同的类型,具有不同的语义和操作。一般来说,将它们混合到同一语法中不是一个好主意。指针不是它们的值:它们可以指向它们引用的类型以外的类型(典型的,在继承的情况下)。因此,通常最好让指针取消引用保持显式

无论如何,保存到流中的“指针值”(不是“pointe*d*value”)没有任何意义,因为该值(内存地址)在流读取时将毫无意义

如果您正确地想要“保存所指向的对象”,那么在保存指针时,您应该保存一些告诉“您正在保存的对象类型”的内容,然后以多态方式保存对象(通过调用虚拟函数)o同时,您还必须跟踪循环引用,以避免多次保存同一对象(并将其作为不同对象加载回),因此还需要“标识”

要重新加载对象,应首先读取为描述类型而保存的元数据,并在此基础上创建相应的对象,然后将其成员重新分配给提取时加载的数据。(或者,如果仅保存了标识,则将指针指向已重新创建的相应对象)


所有这些东西都被冠以序列化的名称。有很多解决方案,你可能应该用谷歌搜索该密钥。

你想让这个重载做什么?我不确定这是个好主意…与其写
*f这听起来不是个好主意…@OliCharlesworth:想解释一下为什么吗?@ronag:它掩盖了什么发生。你抹去了指针和它的指针对象之间的区别。这是两个不同的对象,
*
是保持区别的一个小代价。我不想保存“指向”的内容,我想“发送”到“指向”的内容。这个问题与序列化无关。@ronag它有:如果你想“发送”,必须有人“接收”。要“接收”,必须能够重建。如果某些信息丢失,则无法重建。保存只是“发送”和“接收”的一种特殊情况“发生在不同的时间。这里没有序列化,只是简单的方法调用。@ronad:我不坚持。但你几周后会回来!同样地。同时我建议你看看sehe的答案。它之所以有效,是因为(1)模板参数,(2)对于更复杂的CasyEa,模板模板参数位有点棘手。需要再次找到我的MMODEC++设计书籍。不知怎么没人注意到我之前的Sfink版本被破坏了(接受任何<代码> SyddypTr>代码>,因为指向不完整类型的指针不是问题)。我已经发布了一个更好的方法…
template<typename T>
struct foo
{
    virtual foo& operator<<(const T& e) = 0;
};

foo<int> f1;
f1 << 1;

std::shared_ptr<foo<int>> f2(new foo<int>());
f2 << 1;
template<typename T, typename U>
const std::shared_ptr<T>& operator<<(const std::shared_ptr<T>& o, const U& e)
{
    *o << e;
    return o;
}
template<typename T, typename U>
const std::shared_ptr<foo<T>>& operator<<(const std::shared_ptr<foo<T>>& o, const U& e)
{
    *o << e;
    return o;
}
template<typename T, typename U>
const std::shared_ptr<foo<T>>& operator<<(const std::shared_ptr<foo<T>>& o, const T& e)
{
    *o << e;
    return o;
}
struct c    
{    
};

struct a
{
    a();
    a(c); // implicit conversion
};

struct b
{
    operator a(); // implicit conversion
};

auto f = std::make_shared<foo<a>>();
f << c; // doesn't work.
f << b; // doesn't work.
template <typename T>
class is_funky : public boost::false_type {};

template <typename S>
class is_funky< Foo<S> > : public boost::true_type {};

template<typename T, typename U>
typename boost::enable_if< is_funky<T>, const boost::shared_ptr<T>& >::type 
operator<<(const boost::shared_ptr<T>& o, const U& e)
{
    *o << e;
    return o;
}
#include <iostream>
#include <memory>
using namespace std;

template<typename T> struct foo {
    virtual foo& operator<<(const T& e) const { std::cout << "check foo\n"; }
};

//////
// derived instances

struct derived : foo<int> {
    virtual derived& operator<<(const int& e) const { std::cout << "check derived\n"; }
};

template<typename T> struct genericDerived : foo<T> {
    virtual derived& operator<<(const T& e) const { std::cout << "check genericDerived\n"; }
};
template<typename T, typename U, template <typename> class X>
const std::shared_ptr<X<T>>& operator<<(const std::shared_ptr<X<T>>& o, const U& e)
{
    *o << e;
    return o;
}

int main()
{
    auto f = make_shared<foo<int>>();
    f << 1;

    auto d = make_shared<derived>();
    d << 2; // compile error

    auto g = make_shared<genericDerived<int>>();
    g << 3; // SUCCESS!
}
#include <type_traits>
namespace detail
{
    template<typename Foo, typename T>
        const std::shared_ptr<Foo>& dispatch_lshift(
                  const std::shared_ptr<Foo>& o, const T& e, 
                  const std::true_type& enabler)
        {
            *o << e;
            return o;
        }
}

template<typename Foo, typename T>
    const std::shared_ptr<Foo>& operator<<(const std::shared_ptr<Foo>& o, const T& e)
{
    return detail::dispatch_lshift(o, e, std::is_convertible<Foo*, foo<T>* >());
}

int main()
{
    auto f = make_shared<foo<int>>();
    f << 1;

    auto d = make_shared<derived>();
    d << 2;

    auto g = make_shared<genericDerived<int>>();
    g << 3;

    auto x = make_shared<int>();
    // x << 4; // correctly FAILS to compile    
}