"No Matching Constructor" 尝试实例化模板对象时出错 Class
"No Matching Constructor" Error When Trying to Instantiate Object of a Template Class
编辑:
- 对于
this
以及我的模板 class 末尾缺少 ;
感到非常抱歉;我在复制和粘贴我的代码时遇到了一些问题,所以我手动复制了一些代码并将这些部分弄乱了。
- 重新打开 IDE 后,错误神奇地消失了。也许 Repl.it 遇到了一些问题。现在的错误信息不同了。如果我自己无法解决这个错误,我会提出一个新问题。
感谢 HugoTeixeira, Matthew Fisher, and user4581301 的周到回复。
我在Group.h
中有以下代码:
template <typename T, int N> class Group
{
public:
T values[N];
Group(T args[])
{
for (int i = 0; i < N; i++)
{
values[i] = args[i];
}
}
Group()
{
Group((T[]){0, 0, 0});
}
};
在main.cpp
中,我有这个代码:
#include "Group.h"
int main()
{
Group<double, 3> * v1 = new Group<double, 3>();
}
当我尝试 运行 这段代码时,我的 IDE 给出了错误:
no matching constructor for initialization of 'Group<double, 3>'
我试过编写这段代码,但去掉了模板,它运行良好。我做错了什么?
这似乎是编译器的边缘情况。为一个 C++ 编译器而不是另一个编译器编译各种风格。下面的代码适用于 gcc 和 clang。
template <typename T, int N> class Group
{
public:
T values[N];
Group(T args[])
{
for (int i = 0; i < N; i++)
{
values[i] = args[i];
}
}
Group()
{
Group((T[]){0, 0, 0});
}
};
int main()
{
Group<double, 3> * v1 = new Group<double, 3>();
}
您的代码存在一些问题:
调用另一个构造函数:如果你想在C++中调用另一个构造函数,你不能使用this
关键字(如Java)。您必须在冒号(又名 initializer list)之后执行此操作,如下所示:
Group(): Group((T[]){0, 0, 0})
{}
Class 定义以分号结尾:在 C++ 中,class 定义(模板化或非模板化)必须以分号结尾.你忘了把它添加到你的代码中:
class A {
...
}; <<--- end with a semi-colon
原始指针:理想情况下,您的代码不应使用原始指针。有智能指针可以让你的代码更优雅,更容易维护。例如,您可以使用 std::unique_ptr
或 std::shared_ptr
(视情况而定)。这是 C++14 中的一个简单示例:
auto v1 = std::make_unique<Group<double, 3>>();
我将转向不同的方向并抛弃那些 for a std::initializer_list
(documentation) and a delegated constructor。
template <typename T, size_t N>// replaced int with size_t.
//why allow a negative size?
class Group
{
public:
T values[N];
Group(std::initializer_list<T> list)
{
// may be different sizes
size_t copylen = std::min(list.size(), N);
std::copy(list.begin(),
list.begin()+copylen,
values); // copy all we can
//default initialize remainder, if any
for (size_t i = copylen; i < N; i++)
{
values[i] = T();
}
}
Group():Group{T()} // might be a cleaner way to do this.
// I don't know it.
{
}
/* this may be more efficient. A good compiler can optimize this
down to next-to-nothing
Group()
{
for (size_t i = 0; i < N; i++)
{
values[i] = T();
}
}
*/
};
通过以上内容,您可以处理更多类型的案例。例如,
int main()
{
Group<double, 3> v0; //none
Group<double, 3> v1{1.0}; // too few
Group<double, 3> v3{1.0, 2.0, 3.0};
Group<double, 3> v4{1.0, 2.0, 3.0, 4.0}; // too many
Group<std::string, 3> s2{"A", "B"}; // non-numeric
}
编辑:
- 对于
this
以及我的模板 class 末尾缺少;
感到非常抱歉;我在复制和粘贴我的代码时遇到了一些问题,所以我手动复制了一些代码并将这些部分弄乱了。 - 重新打开 IDE 后,错误神奇地消失了。也许 Repl.it 遇到了一些问题。现在的错误信息不同了。如果我自己无法解决这个错误,我会提出一个新问题。
感谢 HugoTeixeira, Matthew Fisher, and user4581301 的周到回复。
我在Group.h
中有以下代码:
template <typename T, int N> class Group
{
public:
T values[N];
Group(T args[])
{
for (int i = 0; i < N; i++)
{
values[i] = args[i];
}
}
Group()
{
Group((T[]){0, 0, 0});
}
};
在main.cpp
中,我有这个代码:
#include "Group.h"
int main()
{
Group<double, 3> * v1 = new Group<double, 3>();
}
当我尝试 运行 这段代码时,我的 IDE 给出了错误:
no matching constructor for initialization of 'Group<double, 3>'
我试过编写这段代码,但去掉了模板,它运行良好。我做错了什么?
这似乎是编译器的边缘情况。为一个 C++ 编译器而不是另一个编译器编译各种风格。下面的代码适用于 gcc 和 clang。
template <typename T, int N> class Group
{
public:
T values[N];
Group(T args[])
{
for (int i = 0; i < N; i++)
{
values[i] = args[i];
}
}
Group()
{
Group((T[]){0, 0, 0});
}
};
int main()
{
Group<double, 3> * v1 = new Group<double, 3>();
}
您的代码存在一些问题:
调用另一个构造函数:如果你想在C++中调用另一个构造函数,你不能使用this
关键字(如Java)。您必须在冒号(又名 initializer list)之后执行此操作,如下所示:
Group(): Group((T[]){0, 0, 0})
{}
Class 定义以分号结尾:在 C++ 中,class 定义(模板化或非模板化)必须以分号结尾.你忘了把它添加到你的代码中:
class A {
...
}; <<--- end with a semi-colon
原始指针:理想情况下,您的代码不应使用原始指针。有智能指针可以让你的代码更优雅,更容易维护。例如,您可以使用 std::unique_ptr
或 std::shared_ptr
(视情况而定)。这是 C++14 中的一个简单示例:
auto v1 = std::make_unique<Group<double, 3>>();
我将转向不同的方向并抛弃那些 std::initializer_list
(documentation) and a delegated constructor。
template <typename T, size_t N>// replaced int with size_t.
//why allow a negative size?
class Group
{
public:
T values[N];
Group(std::initializer_list<T> list)
{
// may be different sizes
size_t copylen = std::min(list.size(), N);
std::copy(list.begin(),
list.begin()+copylen,
values); // copy all we can
//default initialize remainder, if any
for (size_t i = copylen; i < N; i++)
{
values[i] = T();
}
}
Group():Group{T()} // might be a cleaner way to do this.
// I don't know it.
{
}
/* this may be more efficient. A good compiler can optimize this
down to next-to-nothing
Group()
{
for (size_t i = 0; i < N; i++)
{
values[i] = T();
}
}
*/
};
通过以上内容,您可以处理更多类型的案例。例如,
int main()
{
Group<double, 3> v0; //none
Group<double, 3> v1{1.0}; // too few
Group<double, 3> v3{1.0, 2.0, 3.0};
Group<double, 3> v4{1.0, 2.0, 3.0, 4.0}; // too many
Group<std::string, 3> s2{"A", "B"}; // non-numeric
}