允许/禁用模板的speicifc copy ctor和赋值操作

时间:2016-09-24 00:42:47

标签: c++ templates c++11

我想知道是否可以通过模板实现某些功能。 我想要做的是允许特定的复制ctors和assigment运营商'从一个模板到另一个模板并禁用其他模板。

我认为我只管理了我想要的其中一件事,所以我提供下面的课程。 对于复制ctors或赋值运算符,我希望能够执行以下操作

  • Foo<false>Foo<false>总是确定
  • Foo<true>只应被允许复制或分配给Foo<false>

我不确定是否可能......

#include <iostream>
#include <type_traits>
using namespace std;

template<bool Owner>
class Foo
{
    static constexpr bool owner_ = Owner;

public: 
    Foo() {std::cout << "ctor\n";}
    Foo operator=(const Foo& foo) { std::cout << "assignment\n";}
    Foo(const Foo& foo) { std::cout << "copy ctor \n"; }

    template <bool U>
    Foo( const Foo<U>& other)
    {
        std::cout << "copy ctor2 \n"; 
    }

    template <bool U>
    Foo<false>& operator=( const Foo<U>& other)
    {
        std::cout << "assignment 2 \n"; 
        return *this;
    }

    template < bool B_ = Owner, typename = std::enable_if_t <B_> >
    void bar1() {
        std:cout << "bar1 " << owner_ << "\n";
    }

    void bar2() {std:cout << "bar2 " << owner_ << "\n";}
};

目前,我唯一成功的是operator=适用于Foo<false> = Foo<true>Foo<false>Foo<false>即可,但这也允许所有其他转化,因此可以Foo<true>Foo<true>

1 个答案:

答案 0 :(得分:1)

当然有可能。在C ++中可以做任何事情。

您的问题并非100%明确所有组合的预期行为,但这很容易实现,可以轻松调整:

#include <iostream>

// Helper class

template<bool from, bool to> class ok_to_copy_foos;

// Define all valid conversions as specializations:

template<>
class ok_to_copy_foos<false, false> {

public:
    typedef bool type;
};

template<>
class ok_to_copy_foos<true, false> {

public:
    typedef bool type;
};

////////////////////////////////////////////////////////////////////

template<bool Owner>
class Foo {

public:

    Foo() {}

    template<bool U, typename allow=typename ok_to_copy_foos<U, Owner>::type>
    Foo(const Foo<U> &)
    {
        std::cout << "copy ctor \n";
    }

    template<bool U, typename allow=typename ok_to_copy_foos<U, Owner>::type>
    Foo &operator=(const Foo<U> &)
    {
        std::cout << "assignment\n";

        return *this;
    }
};

void foo()
{
    Foo<false> f1;
    Foo<true> t1;

    // These ones will compile:
    Foo<false> f2(f1);
    f2=f1;
    f2=t1;

    //   These ones will not compile
    //
    //      t1=f2;
    //  Foo<true> t2(f2);
}

编辑:看起来还需要添加显式复制构造函数和赋值运算符。删除默认值是不够的:

Foo(const Foo &o)
{
    typename ok_to_copy_foos<Owner, Owner>::type dummy;
}

Foo &operator=(const Foo &o)
{
    typename ok_to_copy_foos<Owner, Owner>::type dummy;

    return *this;
}