尝试实例化模板类的对象时出现“没有匹配的构造函数”错误

时间:2018-08-26 02:36:37

标签: c++ templates instantiation

编辑:

  1. 对于this以及模板类末尾缺少;,我感到非常抱歉;我在复制和粘贴代码时遇到了一些问题,因此我手动复制了一些代码并将这些部分弄乱了。
  2. 重新打开IDE后,错误消失了。也许Repl.it遇到了一些问题。现在错误消息有所不同。如果我无法自行解决此错误,我将提出一个新问题。

感谢HugoTeixeiraMatthew Fisheruser4581301的周到答复。


我在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>'

我尝试编写此代码,但是减去了模板,它运行良好。我在做什么错了?

3 个答案:

答案 0 :(得分:3)

您的代码存在一些问题:

调用另一个构造函数:如果要在C ++中调用另一个构造函数,则不能使用this关键字(如Java)。您必须在冒号(又名 initializer list )之后执行此操作,

Group(): Group((T[]){0, 0, 0})
{} 

类定义以分号结尾:在C ++中,类定义(是否带模板)必须以分号结尾。您忘记将其添加到代码中了:

class A {
    ...
};  <<--- end with a semi-colon

原始指针:理想情况下,您的代码不应使用原始指针。有一些智能指针可以使您的代码更优雅,更易于维护。例如,您可以使用std::unique_ptrstd::shared_ptr(视情况而定)。这是C ++ 14中的一个简单示例:

auto v1 = std::make_unique<Group<double, 3>>();

答案 1 :(得分:1)

对于编译器来说,这似乎是一个极端的情况。一个C ++编译器可以编译各种样式,而另一种则不能。下面的代码在gcc和clang上对我有用。

" %[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^\n]"

答案 2 :(得分:1)

我要朝另一个方向前进,将那些array casts and other dodgy behavior抛弃到std::initializer_listdocumentation)和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();
            }
        }
*/
};

Documentation for std::copy

使用上述方法,您可以处理更多种情况。例如,

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
}