Ошибка «Нет подходящего конструктора» при попытке создания объекта класса шаблона - PullRequest
0 голосов
/ 26 августа 2018

Редактировать:

  1. Я очень сожалею о this и отсутствии ; в конце моего класса шаблона;У меня были некоторые проблемы с копированием и вставкой кода, поэтому я скопировал часть кода вручную и испортил эти части.
  2. После повторного открытия IDE ошибка просто волшебным образом исчезла.Возможно, у Repl.it возникли проблемы.Сообщение об ошибке теперь другое.Если я не смогу решить эту ошибку самостоятельно, я задам новый вопрос.

Спасибо HugoTeixeira , Мэтью Фишеру и 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>'

Я пытался написать этот код, но без шаблона, и он работал нормально.Что я делаю не так?

Ответы [ 3 ]

0 голосов
/ 26 августа 2018

Есть несколько проблем с вашим кодом:

Вызов другого конструктора : Если вы хотите вызвать другой конструктор в C ++, вы не можете использовать ключевое слово this (как в Java). Вы должны сделать это после двоеточия (он же список инициализаторов ), например:

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

Определения классов заканчиваются точкой с запятой : В C ++ определение класса (шаблонное или нет) должно заканчиваться точкой с запятой. Вы забыли добавить его в свой код:

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

Необработанные указатели : В идеале ваш код не должен использовать необработанные указатели. Есть умные указатели, которые могут сделать ваш код более элегантным и простым в обслуживании. Вы можете, например, использовать std::unique_ptr или std::shared_ptr (в зависимости от ситуации). Вот простой пример в C ++ 14:

auto v1 = std::make_unique<Group<double, 3>>();
0 голосов
/ 26 августа 2018

Я собираюсь идти в другом направлении и угробить эти приведения массива и другое хитрое поведение для std::initializer_list ( документация ) и делегированный конструктор .

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();
            }
        }
*/
};

Документация для 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
}
0 голосов
/ 26 августа 2018

Кажется, это крайние случаи для компиляторов. Различные варианты компилируются для одного компилятора 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>();
}
...