2

I've been attempting a little SFINAE at making a way to determine if a generic type T has a copy constructor I can use. Here is where I currently am.

template <bool statement, typename out>
struct Failable
{
    typedef out Type;
};
//This class is only used to insert statements that 
//could encounter substitution failure


template <typename O>
struct COPY
{
    template <typename T>
    typename Failable<true == sizeof(&T::T(const T&)), char>::Type copy(int)
    {}

    template <typename T>
    typename Failable<true, int>::Type copy(...)
    {}

};

However, this is also where I'm kinda stuck. &T::T(const T&) is obviously an invalid statement, as we can't provide an argument list with a pointer-to-member, even if a p-t-m-function. I could always try to specify some sort of void (T::*ptmf)(const T&) = &T::T, and hope it implicitly determines the right overloaded constructor to put into the pointer to member function, but that also implies that Constructors have a specific return type, which I would have to specify.

Does anyone else have any ideas with which I can trek forth? (I also need to apply a similar concept to checking for an assignment operator.)

Thanks in advanced.

Serge
  • 1,974
  • 6
  • 21
  • 33

2 Answers2

8

You could use std::is_copy_constructible and std::is_assignable for this.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • 1
    ...why is it that a potentially difficult question just has to have easy answers? *sigh* Thanks for letting me know about this! I'm hoping to see if there's a way to implement it manually, though =) – Serge Aug 27 '12 at 06:14
  • 1
    @Serge: you might look at the http://stackoverflow.com/questions/2733377/is-there-a-way-to-test-whether-a-c-class-has-a-default-constructor-other-than/2770326#2770326 - change the test to something like `sizeof U(*(U*)0))` (note `U(U())` also requires default constructibility so isn't good). – Tony Delroy Aug 27 '12 at 06:48
2

You can do with your code, just need to modify it a little bit.

template <bool statement, typename out>
struct Failable
{
     typedef out Type;
}; 

template <typename O>
struct COPY
{

     static O MakeO();

     template <typename U> // U and T are the same type
     static typename Failable<(sizeof U(MakeO())), char>::Type copy(int);

     template <typename U>
     static typename Failable<true, int>::Type copy(...);

     enum { value = sizeof(char) == sizeof( copy<O>(0) ) };
};
  • I tried to use this solution as I need to use an old g++. If the copy ctor is private an error message is presented `error: 'CA::CA(const CA&)' is private. Could it be avoided? Otherwise how could it be that there is no copy ctor? – TrueY Mar 27 '14 at 14:22
  • Actually it does work with g++ 4.7+. At first I tried with 4.1.2 and it failed. THX! – TrueY Mar 31 '14 at 09:51
  • `// U and T are the same type` Where's `T`? Do you mean `O`? – Adrian Mar 29 '19 at 14:26
  • The COPY::value will be 1 but std::stringstream has no copy ctor. I think this template class is correct and it is a strange feature of STL. Why is COPY::value == 1? – mhd Jan 23 '20 at 22:24