这是我的类,其中构造函数调用方法作为初始值设定项。构造函数和这些方法的签名是相同的(唯一的区别是有些是构造函数,而另一些是返回某些内容的方法)
#include <iostream>
#include <vector>
#include <type_traits>
#include <concepts>
// TMyClass ********************************************************************************
template <size_t Size>
class TMyClass {
public:
using TData = std::vector<size_t>;
private:
TData data;
protected:
template <std::integral size_type>
TData InitData(const size_type(&arr)[Size]) {
std::vector<size_t> tmp(Size);
for (size_t i = 0; i < Size; ++i) {
tmp[i] = arr[i];
}
return tmp;
}
template <std::integral size_type>
TData InitData(const size_type* arr, size_t size = Size) {
if (size != Size) throw;
std::vector<size_t> tmp(Size);
for (size_t i = 0; i < Size; ++i) {
tmp[i] = arr[i];
}
return tmp;
}
public:
template <std::integral size_type>
TMyClass(const size_type(&arr)[Size])
: data(InitData(arr)) // <------------------ ERROR
{}
template <std::integral size_type>
TMyClass(const size_type* arr, size_t size = Size)
: data(InitData(arr, size))
{}
};
// M A I N ********************************************************************************
int main()
{
int arr[3] = { 3, 4, 5 };
TMyClass<3> obj1(arr);
std::vector<int> vec = { 1, 2, 3 };
TMyClass<3> obj2(vec.data()); // <------------------ ?????
std::cout << "\n\n - the end -\n";
std::cout << "press [Enter]...";
std::cin.get();
}
结果,我收到错误(代码中的行标记为“<-------------------- ERROR”):
TMyClass<3>::InitData:对重载函数的不明确调用
看起来一切都是合乎逻辑的,纠正是
template <std::integral size_type>
TData InitData(const size_type* arr, size_t size) {
// ...
}
(删除参数的默认值size)解决了问题。
但!那么为什么线上不会出现这个错误
TMyClass<3> obj2(vec.data()); // <------------------ ?????
毕竟在构造函数中
template <std::integral size_type>
TMyClass(const size_type* arr, size_t size = Size)
: data(InitData(arr, size))
{}
该参数的默认值size仍然存在。
PS:问题不在于课程的逻辑:什么是正确/不正确?问题是:为什么在相同的(在我看来)情况下会有不同的行为?
PPS:使用标准 type_traits
模板 <类型名称 size_type, std::enable_if_t< std::is_integral_v<size_type>, bool > = true>
给出相同的结果
PPS:在 Visual Studio 和 Qt 上测试
因为存在隐式数组到指针的转换,但反之则不然:)
看来我通过@Harry 和@isnullxbh 找到了答案。确实,我的猜测是:
不是真的。我没有密切关注类型转换。
代码的行为完全符合我的预期: