microsoft / microsoft/STL

<deque> : A deque<T> where T is move-only, when nested in vector, does not compile

Open
#1,036 8 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug vNext
Dominant language
C++
Stars
11.1k
Forks
1.7k
Avg merge
4d 15h
Merged PRs (30d)
22

Description

Describe the bug
A deque<T> where T is move-only, when nested in vector, does not compile.

Command-line test case

d:\Temp2>type repro.cpp
#include <deque>
#include <vector>

struct A
{
        A(const A&) = delete;
};
void f()
{
        std::vector<std::deque<A> > q;
        q.resize(4);
}
int main()
{
        f();
        return 0;
}

d:\Temp2>cl /EHsc repro.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29009.1 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

repro.cpp
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\xmemory(694): error C2280: 'A::A(const A &)': attempting to reference a deleted function
repro.cpp(6): note: see declaration of 'A::A'
repro.cpp(6): note: 'A::A(const A &)': function was explicitly deleted
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\deque(821): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,const A&>(_Alloc &,_Objty *const ,const A &)' being compiled
        with
        [
            _Alloc=std::allocator<A>,
            _Ty=A,
            _Objty=A
        ]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\deque(820): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,const A&>(_Alloc &,_Objty *const ,const A &)' being compiled
        with
        [
            _Alloc=std::allocator<A>,
            _Ty=A,
            _Objty=A
        ]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\deque(662): note: see reference to function template instantiation 'void std::deque<A,std::allocator<A>>::emplace_back<const A&>(const A &)' being compiled
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\deque(630): note: see reference to function template instantiation 'void std::deque<A,std::allocator<A>>::_Construct<std::_Deque_unchecked_const_iterator<std::_Deque_val<std::_Deque_simple_types<_Ty>>>>(_Iter,_Iter)' being compiled
        with
        [
            _Ty=A,
            _Iter=std::_Deque_unchecked_const_iterator<std::_Deque_val<std::_Deque_simple_types<A>>>
        ]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\deque(630): note: see reference to function template instantiation 'void std::deque<A,std::allocator<A>>::_Construct<std::_Deque_unchecked_const_iterator<std::_Deque_val<std::_Deque_simple_types<_Ty>>>>(_Iter,_Iter)' being compiled
        with
        [
            _Ty=A,
            _Iter=std::_Deque_unchecked_const_iterator<std::_Deque_val<std::_Deque_simple_types<A>>>
        ]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\deque(626): note: while compiling class template member function 'std::deque<A,std::allocator<A>>::deque(const std::deque<A,std::allocator<A>> &)'
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\xmemory(694): note: see reference to function template instantiation 'std::deque<A,std::allocator<A>>::deque(const std::deque<A,std::allocator<A>> &)' being compiled
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\vector(1695): note: see reference to class template instantiation 'std::deque<A,std::allocator<A>>' being compiled
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\vector(1685): note: while compiling class template member function 'void std::vector<std::deque<A,std::allocator<A>>,std::allocator<std::deque<A,std::allocator<A>>>>::_Tidy(void) noexcept'
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\vector(673): note: see reference to function template instantiation 'void std::vector<std::deque<A,std::allocator<A>>,std::allocator<std::deque<A,std::allocator<A>>>>::_Tidy(void) noexcept' being compiled
repro.cpp(10): note: see reference to class template instantiation 'std::vector<std::deque<A,std::allocator<A>>,std::allocator<std::deque<A,std::allocator<A>>>>' being compiled

Expected behavior
Should compile

STL version

Microsoft Visual Studio Professional 2019 Preview
Version 16.7.0 Preview 3.1

Additional context
Other repro:

#include <iostream>
#include <deque>
#include <vector>

struct Data {
	explicit Data(int const time) : m_Time(time) { } 
	Data(Data&& rhs) : m_Time(rhs.m_Time) { }
	Data& operator=(Data&& rhs) { m_Time = rhs.m_Time; return *this; } 
	~Data() { }
	Data& operator=(Data const& rhs) = delete; 
	Data(Data const& rhs) = delete; 
	int m_Time; 
};


struct Map1 {
	typedef std::deque<Data> ValType; // OK with vector

	Map1() : m_Data() { } ValType& operator[](int const key)
	{
		auto it = m_Data.begin();
		if (m_Data.end() == it)                  // OK if commented out
		{                                        // OK if commented out 
			m_Data.emplace_back(key, ValType()); // OK if commented out 
			it = m_Data.end() - 1;               // OK if commented out 
		}                                        // OK if commented out
		return it->second;
	}
	std::vector<std::pair<int const, ValType> > m_Data;
};

int main()
{ 
	Map1 xxxxx; auto& ee = xxxxx[0];
	ee.emplace_back(1);
}

Yet another repro:

#include <vector>
#include <deque>
class Key {
public:
 Key() = default;
 template <typename U>
 Key(U&& u) {}
};
struct MoveOnly {
 MoveOnly() = default;
 MoveOnly(const MoveOnly &) = delete;
 MoveOnly &operator=(const MoveOnly &) = delete;
 MoveOnly(MoveOnly &&) = default;
 MoveOnly &operator=(MoveOnly &&other) = default;
 ~MoveOnly() = default;
};
using Value = std::vector<MoveOnly>;
struct Pair {
 Pair() = default;
 Pair(const Pair&) = default;
 Pair(Pair&&) = default;
 Pair &operator=(const Pair&) = delete;
 Pair &operator=(Pair &&other) { return *this; }
 ~Pair() = default;
 const Key first = Key();
 Value second = Value();
};
int main() {
 std::vector<Pair> data;
 data.emplace_back();
 return 0;
}

Also tracked as:

  • DevCom-33006 and VSO-399383/ AB#399383 ("Problem with nested deque")
  • DevCom-536767 and VSO-851210/ AB#851210 ("Compilation failure in complex move-only case")

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the minimal / case with a move-only A and inspect the and implementations implicated by the diagnostic. Compare it with the additional nested move-only repros; done means these cases compile as expected under the reported MSVC configuration.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.