Opened 7 years ago
Closed 7 years ago
#11959 closed Bugs (wontfix)
boost::is_copy_constructible triggers copy constructor generation on Visual Studio 2013 Update 4
Reported by: | Owned by: | John Maddock | |
---|---|---|---|
Milestone: | To Be Determined | Component: | type_traits |
Version: | Boost 1.60.0 | Severity: | Problem |
Keywords: | Cc: |
Description
When using boost::is_copy_constructible on Visual Studio 2013 (Update 4, not tested with Update 5), the compiler generates a copy constructor and produces an error if the copy constructor cannot be generated. On the other side, std::is_copy_constructible is implemented and works fine.
As a result, it would be a solution to make boost::is_copy_constructible inherit from std::is_copy_constructible on this specific compiler version.
Change History (8)
comment:1 by , 7 years ago
comment:2 by , 7 years ago
To be more precise it's when we derive from a class which have its copy constructor private (it might be a known case)
class NoCopy { private: NoCopy(const NoCopy&); }; class DerivedNoCopy : public NoCopy { }; static const int ok = !boost::is_copy_constructible<NoCopy>::value; // OK static const int error = !boost::is_copy_constructible<DerivedNoCopy>::value; // error C2248: 'NoCopy::NoCopy' : cannot access private member declared in class 'NoCopy'
comment:3 by , 7 years ago
OK this is a known issue, our implementation notes:
// Special version for VC12 which has a problem when a base class (such as non_copyable) has a deleted // copy constructor. In this case the compiler thinks there really is a copy-constructor and tries to // instantiate the deleted member. std::is_copy_constructible has the same issue (or at least returns // an incorrect value, which just defers the issue into the users code) as well. We can at least fix // boost::non_copyable as a base class as a special case:
In other words, deferring to std::is_copy_constructible doesn't really help because it returns the wrong value... which means the error will still be triggered later in the client code when the copy constructor is actually used (if it's not used, then why check is_copy_constructible?)
So I don't see any fix for this?
comment:4 by , 7 years ago
Why not using std::is_copy_constructible which is available for this compiler and works as expected ?
namespace boost { template<typename T> struct is_copy_constructible : public std::is_copy_constructible<T> {}; }
comment:5 by , 7 years ago
Sorry i didn't see the end of your comment. Why are you saying that std::is_constructible returns a wrong value ? It worked and solved this issue for me in this case. But maybe it doesn't for other cases... Maybe the last compiler updates (4 and 5) changed results of std::is_copy_constructible. Have you tested my test case with the std version ?
comment:6 by , 7 years ago
Given:
class NoCopy { private: NoCopy(const NoCopy&); }; struct has_not6 : public NoCopy { has_not6(int a); }; static_assert(!std::is_copy_constructible<has_not6>::value, "Ooops");
VC12 static asserts, but VC14 and gcc-4.9.2 pass as expected.
This is with cl version 18.00.31101.
The point is that an is_copy_constructible that returns the wrong value is as useless as one that doesn't compile, given that you should only use the trait if the copy-constructor is going to be used. The advantage of our own version is that it does handle classes that derive from boost::noncopyable correctly - removing that support would almost certainly break quite a bit of boost code.
comment:7 by , 7 years ago
I agree. In fact in my case it was a more complicated issue and you are right it gives wrong value. I had an another filter which avoided copy constructor to be used. The fact is with the boost version I couldn't accomplish what I've planned to because I used it on external classes which cannot have noncopyable base (Qt for example). It is a design which in fine is quite good because it allows at least to use one or another version depending on what we try to achieve (boost or std). The bug can be marked resolved or else, it's good on my side, thank you for taking time to analyse with me the issue.
comment:8 by , 7 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Another solution is to explicitly specialize is_copy_constructible for your type.
I'm having trouble reproducing, can you provide a test case?