简体   繁体   中英

How to implicitly cast templated constructor arguments?

I'm overloading the constructor of a templated class A with different input types, for both scalar and container-type arguments:

template<typename T>
class A {
public:
    A();
    A(T&& _val) { printf("non-template constructor\n");} ;
    template<typename iT> A(const iT& _cont) { printf("template constructor\n");};

};


int main(int argc, char const *argv[]) {


    A<float> foo1(0.9);                     //template constructor
    A<float> foo2((float)0.9);              //no-template constructor 
    A<float> foo3(std::vector<int>(5,8));   //template constructor


    return 0;
}

However, is there a way to call force the non-template constructor on implicitly castable types eg passing a double to constructor A<float>() ?

Yes, you can add a SFINAE-constraint to your constructor template:

template<typename iT,
         std::enable_if_t<!std::is_convertible_v<iT&&, T>>* = nullptr>
A(const iT&) { printf("template constructor\n"); }

This has the effect of causing substitution failure for the deduced type iT when iT&& is convertible to T , which removes the constructor template from the overload set.

(You need to #include <type_traits> for the various library facilities used to express the constraint.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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