2016-09-24 15 views
2

我想知道是否可以实现某些模板。 我想要做的是允许从一个模板到另一个模板的特定“复制ctors和分配操作符”,并禁用其他模板。允许/禁止模板的特殊字体复制和分配操作

我想我管理的只是我想要的东西之一,所以我提供了下面的类。 对于副本构建函数或赋值操作符我希望能够做到以下

  • Foo<false>Foo<false>总是OK
  • 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

当然这是可能的。任何事情都可以在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; 
} 
+0

谢谢,这看起来不错,但我不知道是否有2箱,也可以cought。 这就是 'auto t3(t1);'会工作,所以会'auto ta = t1;' 此外,如果我想添加一些有用的static_assert来说“这不被支持”它会去哪里? – xerion

+0

对不起,我在完成之前意外发布了评论。编译器定义的复制构造函数和assignement似乎允许这两个 – xerion

+0

类似地,我认为''转换专门化甚至没有被使用,而是编译器生成的函数是首选。 – xerion

相关问题