仅限Clang:一对<path,path =“”>可以放置到一个向量中;那么一对<unique_ptr,unique_ptr =“”>;但不是对<path,unique_ptr =“”>:为什么?</path,> </unique_ptr,> </path,>

时间:2013-12-14 12:57:14

标签: c++ c++11 vector compiler-errors clang

我有以下三段代码来演示一个易于重现的问题。

using namespace boost::filesystem;
using namespace std;

int main()
{

    path dummy_path;

    // Snippet 1
    // Two paths
    // Succeeds
    //
    // vector<pair<path, path>> myvec;
    // myvec.emplace_back(dummy_path, dummy_path);

    // Snippet 2
    // Two unique_ptr's
    // Succeeds
    //
    // vector<pair<unique_ptr<int>, unique_ptr<int>>> myvec;
    // myvec.emplace_back(unique_ptr<int>(new int(13)), unique_ptr<int>(new int(12)));

    // Snippet 3
    // A path and a unique_ptr.
    //
    // **FAILS** on Clang, succeeds in Visual Studio
    //
    vector<pair<path, unique_ptr<int>>> myvec;
    myvec.emplace_back(dummy_path, unique_ptr<int>(new int(12)));

}

以下是Clang上的编译器错误:

error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<int, std::__1::default_delete<int> >'(参考该对中的第二个成员,显然是unique_ptr。)

似乎由于某种原因,指示的失败案例导致调用该对的复制构造函数而不是移动构造函数。

这是OS X 10.8.5上的Clang 5.0.2。 (和Windows 11 64位上的VS 11.0.60610.01 Update 3。)

在我的实际应用程序中,数据类型更复杂,但错误归结为此问题中描述的错误。

我的问题有两个:为什么案件表明Clang 失败,即使其他两个案例(包括两种数据类型)都成功了?

也许更重要的是,我可以做些什么来解决这个问题?因为我的实际应用程序更复杂,我没有选择不执行安装(或类似的东西)给定对中的一对 - 但如果有任何其他方法我可以通过这个Clang问题将该对进入该向量,我会非常高兴。

2 个答案:

答案 0 :(得分:2)

问题来自libc ++标准库,因为它内部的pair构造函数要少得多。

即。 libstd ++有以下构造函数:

template<class _U2, class = typename
       enable_if<is_convertible<_U2, _T2>::value>::type>
constexpr pair(const _T1& __x, _U2&& __y)
: first(__x), second(std::forward<_U2>(__y)) { }

允许在Linux上编译样本(使用clang ++)。但是libc ++只有:

pair(const pair&) = default;
pair(pair&&) = default;
constexpr pair();
pair(const T1& x, const T2& y);                          // constexpr in C++14
template <class U, class V> pair(U&& x, V&& y);          // constexpr in C++14
template <class U, class V> pair(const pair<U, V>& p);   // constexpr in C++14
template <class U, class V> pair(pair<U, V>&& p);        // constexpr in C++14
template <class... Args1, class... Args2>
    pair(piecewise_construct_t, tuple<Args1...> first_args,
         tuple<Args2...> second_args);

我想,由于第一个参数是非右值引用,因此应用了pair(const T1& x, const T2& y);


“硬核”解决方案是手动放置此构造函数 - 在系统库中。 pairutility文件中定义。如果您希望能够在其他地方编译代码,可以将修改后的libc ++捆绑到您的项目中 - 这不是什么大问题。

答案 1 :(得分:2)

这是libc ++中的一个错误,抱歉。它已经固定在行李箱上。我相信你可以通过在编译命令中添加以下内容来解决它:

-D_LIBCPP_TRIVIAL_PAIR_COPY_CTOR