C ++括号在委托构造函数中包含初始化列表

时间:2017-07-13 07:48:31

标签: c++ vector constructor initialization

我试图为c ++类提供两个不同的构造函数,包括std :: vector成员:

class A {

    public:

        std::vector<int> p;

        A (std::vector<int> i) { p = i; }

        A (int x, int y, int z) : A ( {x, y, z} ) {}
};

int main () {

    A a ( {1, 2, 3} );

    A a2 (1, 2, 3);

    return 0;
}

第一个构造函数正常工作,但第二个构造函数抛出以下错误:

error: call of overloaded ‘A(<brace-enclosed initializer list>)’ is ambiguous

这两种方法有什么区别?

1 个答案:

答案 0 :(得分:1)

问题出在第二个构造函数中:

# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)

# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_targetsDefined)
set(_targetsNotDefined)
set(_expectedTargets)
foreach(_expectedTarget cpufeatures libtiff libjpeg libwebp libjasper libpng IlmImf tegra_hal libprotobuf opencv_core opencv_flann opencv_imgproc opencv_ml opencv_objdetect opencv_photo opencv_video opencv_dnn opencv_imgcodecs opencv_shape opencv_videoio opencv_highgui opencv_superres opencv_features2d opencv_calib3d opencv_java opencv_stitching opencv_videostab)
  list(APPEND _expectedTargets ${_expectedTarget})
  if(NOT TARGET ${_expectedTarget})
    list(APPEND _targetsNotDefined ${_expectedTarget})
  endif()
  if(TARGET ${_expectedTarget})
    list(APPEND _targetsDefined ${_expectedTarget})
  endif()
endforeach()
if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
  unset(_targetsDefined)
  unset(_targetsNotDefined)
  unset(_expectedTargets)
  set(CMAKE_IMPORT_FILE_VERSION)
  cmake_policy(POP)
  return()
endif()
if(NOT "${_targetsDefined}" STREQUAL "")
  message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
endif()

由于A (int x, int y, int z) : A ( {x, y, z} ) {} 可以同时调用

  • 第一个构造函数:初始化列表A ( {x,y,z} )可以强制转换为{x, y, z}并匹配第一个构造函数。

  • 第二个构造函数本身:正如您可以看到构造函数调用自身的here

std::vector<int>
  

这两种方法有什么区别?

第一个构造函数接受任何整数向量。有效的结构例如是:

A::A(int, int, int):
pushl   %ebp
movl    %esp, %ebp
subl    $8, %esp
// ...
call    A::A(int, int, int)  // <--- recursive call
// ...

第二个构造函数接受三个整数。有效的结构是:

A({1}); A({1, 2}); A({1, 2, 4}); A({1, 2, 3, 4, ...}); ...

正如您所看到的,表达式A({1, 2, 3}); A(1, 2, 3); A{1, 2, 3}; 被两个构造函数都接受,因此它是不明确的(编译器无法以确定的方式知道哪个选择)。