Home How to delete copy/move instantiation of variadic template constructor
Reply: 1

How to delete copy/move instantiation of variadic template constructor

J.Doe
1#
J.Doe Published in 2017-12-07 02:09:07Z

Suppose this is my class:

#include<utility>
#include<type_traits>

template<typename T>
class MyClass {
    T v;
public:
    template<typename...Ts>
    MyClass(Ts&&...args) :v{ std::forward<Ts>(args)... } {}

    MyClass(MyClass const&) = default;
    MyClass(MyClass &&) = default;
};

class OtherClass {
public:
    operator MyClass<int>() {
        return{};
    }
};

int main(){
    MyClass<int> mc;
    MyClass<int> mc2{ mc }; // error: cannot convert from 'MyClass<int>' to 'int'
    OtherClass oc;
    MyClass<int> mc3 {oc};  // error: cannot convert from 'OtherClass' to 'int'
}

How to correctly prevent the variadic template constructor from instantiating a copy/move constructor?

songyuanyao
2#
songyuanyao Reply to 2017-12-07 14:48:00Z

You can apply SFINAE with std::enable_if to restrict the types, e.g.

template <typename... Ts>
struct getFirstType {
    using type = void;
};
template <typename T, typename... Ts>
struct getFirstType<T, Ts...> {
    using type = T;
};

template<typename T>
class MyClass {
    T v;
public:
    // only valid when the first type of parameter pack is NOT MyClass
    template<typename...Ts, 
             typename = std::enable_if_t<
                 !std::is_same_v<MyClass, 
                                 std::decay_t<typename getFirstType<Ts...>::type>>>>
    MyClass(Ts&&...args) :v{ std::forward<Ts>(args)... } {}

    MyClass(MyClass const&) = default;
    MyClass(MyClass &&) = default;
};

LIVE

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.335147 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO