Неоднозначный вызов конструктора с gcc 8.2.1 - PullRequest
3 голосов
/ 26 июня 2019

Эта программа определяет простой контейнер для массива std::unique_ptr<unsigned int>.

#include <memory>
#include <array>
#include <type_traits>

template <unsigned int dim>
class container {
  template <std::size_t... I>
  container(std::array<unsigned int, dim> Ls, std::index_sequence<I...>) : container(std::get<I>(Ls)...) { }

public:
  const std::array<std::unique_ptr<unsigned int>, dim> data;

  template <typename... UInts, class = std::enable_if_t<(sizeof...(UInts) == dim) && (std::is_same_v<UInts, unsigned int> && ...)>>
  container(UInts... Ls) : data{ std::make_unique<unsigned int>(Ls)...} { }

  template <typename Indices = std::make_index_sequence<dim>>
  container(std::array<unsigned int, dim> Ls) : container(Ls, Indices{}) { }
};

int main()
{
  unsigned int x = 1;
  unsigned int y = 2;

  container<2> a({x,y});

  return 0;
}

Однако компиляция с gcc 8.2.1 завершается неудачно со следующей ошибкой.

$ g++ -Wall -pedantic -std=c++17 -o test test.cpp

test.cpp: In function ‘int main()’:
test.cpp:25:23: error: call of overloaded ‘container(<brace-enclosed initializer list>)’ is ambiguous
   container<2> a({x,y});
                       ^
test.cpp:17:3: note: candidate: ‘container<dim>::container(std::array<unsigned int, dim>) [with Indices = std::integer_sequence<long unsigned int, 0, 1>; unsigned int dim = 2]’
   container(std::array<unsigned int, dim> Ls) : container(Ls, Indices{}) { }
   ^~~~~~~~~
test.cpp:6:7: note: candidate: ‘container<2>::container(const container<2>&)’ <deleted>
 class container {
       ^~~~~~~~~
test.cpp:6:7: note: candidate: ‘container<2>::container(container<2>&&)’ <deleted>
make: *** [Makefile:3: test] Error 1

Действительно, конструктор копирования удаляется из-за наличия массива std::unique_ptr (но все же участвует в разрешении перегрузки ).

Странно, на gcc 7.3.0 приведенный выше кодкомпилируется без ошибок и предупреждений.

Кроме того, при определении упрощенного контейнера, имеющего копируемый массив unsigned int, как в следующей программе, с gcc 8.2.1 и gcc 7.3.0 * не возникает ошибок1016 *

#include <array>
#include <type_traits>

template <unsigned int dim>
class container_simple {
  template <std::size_t... I>
  container_simple(std::array<unsigned int, dim> Ls, std::index_sequence<I...>) : container_simple(std::get<I>(Ls)...) { }

public:
  const std::array<unsigned int, dim> data;

  template <typename... UInts, class = std::enable_if_t<(sizeof...(UInts) == dim) && (std::is_same_v<UInts, unsigned int> && ...)>>
  container_simple(UInts... Ls) : data{ Ls...} { }

  template <typename Indices = std::make_index_sequence<dim>>
  container_simple(std::array<unsigned int, dim> Ls) : container_simple(Ls, Indices{}) { }
};

int main()
{
  unsigned int x = 1;
  unsigned int y = 2;

  container_simple<2> a({x,y});

  return 0;
}

Это ошибка компилятора?Если нет, то где же двусмысленность?

...