I have a container-like class that I would like to use only for moving, if the base type is only for moving, but otherwise it could be copied. To make things simpler, suppose that the ability to copy is specified by one parameter of the bool template:
template<bool IsCopyable> struct Foo { Foo(); Foo(const Foo&);
Now I canβt just SEND a copy of ctor, because it requires creating a template, and the template function cannot be a copy of ctor. Also, I cannot just do static_assert() inside a copy of ctor. Although this will lead to an erroneous use of the ctor copy, it also forces the class to inherently copy the construct from the outside (a dash of type std::is_copy_constructible will give true).
By the way, the unfortunate requirement is that it must compile in VC ++ 2012, so I cannot use the fancy SFINAE expression, ctors inheritance, default / deleted functions, or
constexpr if (however, if you have a neat solution for C ++ 17 I still would like to hear it :))
The obvious method is to use specialized specialization. I would prefer not to go this route, because in fact Foo has quite a lot of functionality, and I do not like to repeat myself. However, this is my only option, and I can implement some code exchange using the base class, for example:
// Base functionality template<bool IsCopyable> struct FooBase { FooBase(); // move ctor and assignment can go here FooBase(FooBase&&); FooBase& operator=(FooBase&&); // some generic conversion ctor and assignment that I happen to need template<class T> FooBase(T&& t); template<class T> FooBase& operator=(T&&); // ... all sorts of functionality and datamembers }; // Foo<false> template<bool IsCopyable> struct Foo : FooBase<IsCopyable> { // can't use inheriting ctors in VS 2012, wrap the calls manually: Foo() { } Foo(Foo&& other) : FooBase<IsCopyable>(std::move(other)) { } Foo& operator=(Foo&& other) { FooBase<IsCopyable>::operator=(std::move(other)); return *this; } template<class T> Foo(T&& t) : FooBase<IsCopyable>(std::forward<T>(t)) { } template<class T> Foo& operator=(T&& t) { FooBase<IsCopyable>::operator=(std::forward<T>(t)); return *this; } }; // Foo<true> template<> struct Foo<true> : FooBase<true> { // add these Foo(const Foo&); Foo& operator=(const Foo&); // wrapping calls because of VS 2012: Foo() { } Foo(Foo&& other) : FooBase<true>(std::move(other)) { } Foo& operator=(Foo&& other) { FooBase<true>::operator=(std::move(other)); return *this; } template<class T> Foo(T&& t) : FooBase<true>(std::forward<T>(t)) { } template<class T> Foo& operator=(T&& t) { FooBase<true>::operator=(std::forward<T>(t)); return *this; } };
This is still a bit verbose. Fortunately, it gets cleaner if you can use ctors inheritance and default functions. However, I was hoping there was an easier way, ideally, not using a base class.