The following code doesn’t compile with clang 3.1, using libc++ (don’t know the version, the current one that comes with Xcode). It works fine with other standard libs. Is there an error in my code, or is this a bug in libc++?
#include <map>
#include <string>
using namespace std;
struct A {
A(const map<int, A>& m) {}
};
struct B {
map<string, A> m;
};
The error i’m seeing is in <utility>:
/usr/lib/c++/v1/utility:241:64: No member named 'value' in 'std::__1::is_nothrow_copy_constructible<A>'
I’ve tried to isolate it further, but this is the minimal example I found. Interestingly, when I replace string by int in the second map it works (also when I replace int by string int the first map):
map<string, A> m; // Does not work
map<int, A> m; // Works
This is not exactly an error and I explain you why:
In 1997, shortly before the C++ Standard was completed, the standardization committee received a query: Is it possible to create standard containers with incomplete types? It took a while for the committee to understand the question. What would such a thing even mean, and why on earth would you ever want to do it? The committee eventually worked it out and came up with an answer to the question. (Just so you don’t have to skip ahead to the end, the answer is “no.”) But the question is much more interesting than the answer: it points to a useful, and insufficiently discussed, programming technique. The standard library doesn’t directly support that technique, but the two can be made to coexist.
When you are declaring
const std::map<int, A>&,Ais still incomplete and standard does not enforce implementers to provide support for incomplete types, so if you really need it and you have option to useboost, you can change your container and useboost::containerin place of standard container in compilers that don’t support this.