简体   繁体   中英

SFINAE - enable one function if arguments are copy-constructible and another otherwise

I want a function to be called if the argument are copy-constructible and another function (similar to previous but with extra code). I find that std::is_copy_constructible is not working as expected

#include <iostream>

using namespace std;


struct NoCopy {
    int n;
    NoCopy(const NoCopy&) = delete;
};


template <typename T, 
         typename U, 
         std::enable_if_t<!std::is_copy_constructible_v<U>, int> = 0>
void log_debug(T&& t, U&& u)
{
    
 std::cout<<"\n"<<typeid(U).name()<<" does not have copy constructor; ";  
}
   
   
template <typename T, 
            typename U, 
            std::enable_if_t<std::is_copy_constructible_v<U>, int> = 0>
void log_debug(T&& t, U&& u)
{
    
 std::cout<<"\n"<<typeid(U).name()<<" has copy constructor; ";  
}

int main()
{
    NoCopy a{2};
    log_debug("value is ", a);
    
    std::cout<<"\nstd::is_nothrow_copy_constructible_v  "<<std::is_copy_constructible_v<NoCopy>;  //returns 0 as expected

    return 0;
}


                                                                                                                                                                                                                                    

Output:

6NoCopy has copy constructor;
std::is_copy_constructible_v 0

is_copy_constructible_v seems to work inside main function but not outside

The problem is that here U isn't deduced as NoCopy , but as NoCopy& .

You can fix this by using std::decay_t<U> in your enable_if to strip the cv qualifiers and reference and yield NoCopy like you want.

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