为什么C ++隐式类型转换在结构上能很好地工作而在类上却能以其他方式工作 [英] Why C++ implicit type conversion work's well with structures but in other way with classes
问题描述
我正在尝试使用C ++创建带有动态内存初始化的多维数组,但是当我直接使用函数时,隐式类型转换以一种方式工作,而当我尝试在周围创建类-shell时,隐式类型转换则以另一种方式工作
I'm trying to create a multi-dimensional array with dynamic memory initialisation in C++, but an implicit type conversion works in one way when I work directly with functions, but in another way when I tried to create class-shell around this pointer and named functions as class members.
如果模板类型T(例如int)具有(T *&)类型而不是(T& )作为任何嵌套的指针,但是当我使这些函数成为类成员时,它们甚至无法隐式地将T **转换为(T *&)转换。
If template type T, for example, int, with structures it prefers (T *&) type over (T &) for a pointer of any nesting, but when I made these functions class members, they even can't implicitly make T** to (T*&) transformation.
例如,我知道T ***不是T& ;,但是空函数是我递归的底部,它初始化n维数组(指针,随便什么)。此转换适用于非类函数,但不适用于clas成员函数。
I understand that T***, for instance, is not T&, but empty body function is a bottom of my recursion, that initializes n-dimensional array(pointer, whatever). This conversion works with non-class functions but doesn't work implicitly with clas-member functions.
template<typename T, size_t N>
struct NDimensionalArray {
typedef typename NDimensionalArray<T, N - 1>::type * type;
};
template<typename T>
struct NDimensionalArray<T, 1> {
typedef T * type;
};
template<typename T>
void initializeNDimensionalArray(T &, size_t) { }
template<typename T>
void initializeNDimensionalArray(T *& arr, size_t n) {
arr = new T[n];
for (size_t i = 0; i < n; ++i)
initializeNDimensionalArray(arr[i], n);
}
int main() {
NDimensionalArray<int, 3>::type arr;
initializeNDimensionalArray(arr, 2);
}
template <typename T, size_t N>
class NDimArray {
public:
typename NDimensionalArray<T, N>::type arr{ nullptr };
NDimArray<T, N>::NDimArray() {
init(arr, 0); //exception, cannot transform T*** to T*&,
//invokes T&
}
void init(T &, size_t, int) { }
void NDimArray<T, N>::init(T *& arr, size_t n) {
arr = new T[n];
for (size_t i = 0; i < n; ++i)
init(arr[i], n);
}
}
int main() {
NDimArray<int, 3> arr(2);
}
推荐答案
您不要 t 在您的工作示例中从 int ***
隐式转换为 int *&
。
You don't have an implicit conversion from int ***
to int* &
in your working example.
我们在使用您的模板时扩展类型。
Let's expand the types when we use your template.
NDimensionalArray<int, 3>::type arr;
// a.k.a.
NDimensionalArray<int, 2>::type * arr;
// a.k.a.
NDimensionalArray<int, 1>::type ** arr;
// a.k.a.
int *** arr;
因此,当我们将其传递给 initializeNDimensionalArray
时, T
的推导类型为 int **
,它替代为您
So when we pass it to initializeNDimensionalArray
, the deduced type for T
is int **
, which substitutes to give you
template<>
void initializeNDimensionalArray<int**>(int** *& arr, size_t n) {
arr = new int**[n];
for (size_t i = 0; i < n; ++i)
initializeNDimensionalArray<int*>(arr[i], n);
}
使用另一个参数 int实例化模板的*
,依此类推。
Which instantiates the template with another argument, int *
, and so on.
如果将它包装在一个类中,则 init
从传递给 NDimensionalArray
的单个模板参数中获取 T
的定义,因此它不会t当您传递 int ***
时匹配。您需要 init
成为成员模板。
In the case where you wrap it in a class, your init
gets it's definition of T
from the same single template parameter that you pass to NDimensionalArray
, so it doesn't match when you pass an int ***
to it. You need init
to be a member template.
template <typename T, size_t N>
class NDimArray {
public:
typename NDimensionalArray<T, N>::type arr{ nullptr };
NDimArray() {
init(arr, 0);
}
private:
// T is the type we want here
void init(T &, size_t) { }
// U will be T, T *, T ** etc
template<typename U>
void init(U *& arr, size_t n) {
arr = new U[n];
for (size_t i = 0; i < n; ++i)
init(arr[i], n);
}
}
这篇关于为什么C ++隐式类型转换在结构上能很好地工作而在类上却能以其他方式工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!