The correct answer is Jonathan Wakeley's. I'll leave this as it provides useful information for people who have a similar problem related to insert
.
The short version is that this is caused by a problem in the Standard Library implementation used by GCC 4.7.2, which resulted from a misleading wording used in the C++11 Standard. There is a change proposal for the wording, as well as a fix of the implementation in GCC 4.8.
Long version
This GCC bug entry reports a very similar issue, where insert
is used instead of emplace
. The libstdc++ implementation of insert
follows the Standard, which states about the insert
function (specifically, template <class P> pair<iterator,bool> insert(P&& obj)
):
(§23.5.4.4/5) Remarks: This signature shall not participate in overload resolution unless P is implicitly convertible to value_type
.
libstdc++ seems to have implemented this requirement using an enable_if
statement that checks std::is_convertible<>
for the types involved.
The bug report linked above later states that really std::is_constructible<>
should have been used, and the wording in the Standard should be changed. It links to an LWG (language working group) issue, which proposes a change to the Standard for this already (LWG issue #2005, see the Portland 2012 entry, relevant portion of the proposed change below):
Change 23.5.4.4 [unord.map.modifers] around p. 1 as indicated:
template <class P>
pair<iterator, bool> insert(P&& obj);
[...]
Remarks: This signature shall not participate in overload resolution unless P is implicitly convertible to value_typestd::is_constructible<value_type, P&&>::value
is true.
The proposed change also states that the effect of the insert
function described above should be equivalent to that of emplace(std::forward<P>(obj))
. It is therefore probably safe to say that the issue described in your question is exactly the same problem.
And indeed, the proposed changes seem to be reflected in recent GCC 4.8 snapshots: When you compile your code with GCC 4.8, the is_convertible
check isn't performed and no error message appears.