用gcc 8.2.1调用构造函数

时间:2019-06-26 09:47:36

标签: c++ gcc unique-ptr constructor-overloading

该程序为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(但仍然是participates to the overload resolution)数组,因此删除了复制构造函数。

奇怪的是,在gcc 7.3.0上,上面的代码编译时没有错误或警告。

还定义了一个简化的容器,该容器具有unsigned int的可复制数组,如以下程序所示,gcc 8.2.1和gcc 7.3.0均未发生错误

#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;
}

是编译器错误吗?如果没有,歧义在哪里?

0 个答案:

没有答案