简体   繁体   English

复制构造函数中的“模板typedef”不起作用

[英]“Template typedef” inside a copy constructor doesn't work

Some background: I'm writing a policy-based smart pointer (like SmartPtr in the Loki library), which can have destructive copy semantics like auto_ptr. 背景知识:我正在写一个基于策略的智能指针(例如Loki库中的SmartPtr),它可以具有破坏性的复制语义,例如auto_ptr。 Therefore, it needs to have a template copy constructor taking non-const reference to modify the object being copied. 因此,它需要一个具有非const引用的模板副本构造函数来修改要复制的对象。

What I'm trying to do is to parametrize the constness of the argument taken by copy constructor by some variable in the policy to make it const when destructive copy semantics is not desired. 我想要做的是在不需要破坏性复制语义的情况下,通过策略中的某个变量对复制构造函数采用的参数的常数进行参数化,以使其成为常数。 Here is the simplified code of the idea I've came up to, but, unfortunately, it doesn't work, because the compiler can't deduce template arguments. 这是我想到的简化代码,但不幸的是,它不起作用,因为编译器无法推断出模板参数。 I there any other technique that can be used to achieve the desired behaviour? 我还有其他方法可以用来实现所需的行为吗?

template <typename T, bool isEnabled> struct AddConst {
    typedef T Type;
};

template <typename T> struct AddConst<T, true> {
    typedef const T Type;
};

struct MyCopyPolicy {
    static const bool kIsCopyArgConst = true;
};

template <typename T, class CopyPolicy> struct Foo {

    // A helper struct to achieve "template typedef".
    template <typename T2> struct CopyArg {
        typedef typename AddConst<Foo<T2, CopyPolicy>,
            CopyPolicy::kIsCopyArgConst>::Type Type;
    };

    Foo() {}
    // Template copy constructor. Doesn't work.
    template <typename T2> Foo(typename CopyArg<T2>::Type& rhs) {}
};

int main() {
    Foo<int, MyCopyPolicy> foo1;
    Foo<double, MyCopyPolicy> foo2 = foo1;  // error!
}

Perhaps something like this might work for you. 也许这样的事情可能对您有用。 I've used std::enable_if from C++0x. 我使用了C ++ 0x的std :: enable_if。 You could just as easily use boost's, or roll your own (it's only a couple lines of code). 您可以轻松使用boost或自己滚动(仅几行代码)。

#include <type_traits>

struct MyCopyPolicy {
    static const bool kIsCopyArgConst = true;
};

template <typename T, class CopyPolicy> struct Foo {

    // A helper struct to achieve "template typedef".
    template <typename T2> struct CopyArg {
        typedef CopyPolicy Type;
    };

    Foo() {}

    template <typename T2>
        Foo(const T2& rhs,
                typename std::enable_if<CopyArg<T2>::Type::kIsCopyArgConst>::type* = 0)
            {}
    template <typename T2>
        Foo(T2& rhs,
               typename std::enable_if<!CopyArg<T2>::Type::kIsCopyArgConst>::type* = 0)
            {}
};

int main() {
    Foo<int, MyCopyPolicy> foo1;
    Foo<double, MyCopyPolicy> foo2 = foo1;  // ok!
}

I'm not positive this is optimal. 我不认为这是最佳选择。 This was just shoot-from-the-hip with one of the goals being a minimum distance from where you were heading. 这只是从一杆开枪,目标之一是距您前进的目的地的最小距离。 Perhaps this is where you want to go, or perhaps this will just get you started in the right direction. 也许这就是您要去的地方,或者这只会使您朝正确的方向入手。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM