Функция утилиты не инициализируется в файле .h и не определяется в main.cpp - PullRequest
1 голос
/ 18 мая 2019

Я только изучаю C ++ и столкнулся с проблемой, которую не может решить консольный отладчик Sublime Text. У меня есть stringify функция с двумя аргументами, const auto& arr и const std::string& ch. Я хотел бы иметь возможность инициализировать это в моем файле main.h, который я импортирую в каждый отдельный файл .cpp для своего проекта, чтобы он был доступен для глобальной области.

Я попробовал нормальный способ сделать это, просто определив его сначала в main.h, а затем заполнив остальные в моем main.cpp

main.cpp

std::string stringify(const auto& arr, const std::string& ch)
{
    std::stringstream ss;
    unsigned i = 0;
    for (auto& element : arr) {
        ++i;
        // add element to s
        ss << element;
        // if element isnt the last one.
        (i != arr.size()) ? ss << ch : ss;
    }
    return ss.str();
}

main.h

#ifndef MAIN_H
#define MAIN_H

#include <iostream>
#include <string>
#include <sstream>
#include <array>
#include <vector>
#include <iterator>
#include <algorithm>

std::string stringify(const auto& arr, const std::string& ch);

#endif // MAIN_H

Я постоянно получаю сообщения об ошибке "неопределенная ссылка на функцию" независимо от того, что я пытаюсь , если Я не поместил полное определение функции в main.h. Что мне здесь не хватает? Я читал документы и не могу понять это.

Ответы [ 2 ]

3 голосов
/ 18 мая 2019

Обратите внимание, что использование auto в параметре функции, например, const auto& arr, в настоящее время не является стандартом C ++.Он будет действителен в C ++ 20, но некоторые компиляторы уже реализуют его для других версий C ++ в качестве расширения.

Что он на самом деле делает, так это превращает функцию в шаблон функции, поскольку фактический типпараметра теперь нужно выводить из аргументов функции.Таким образом, объявление

std::string stringify(const auto& arr, const std::string& ch);

по существу эквивалентно

template <typename T>
std::string stringify(const T& arr, const std::string& ch);

Поскольку ваша функция действует как шаблон, ее определение должно быть в заголовочном файле, чтобы компилятор мог создать его экземпляр какнужен всякий раз, когда он используется с новым типом arr.(См. Почему шаблоны могут быть реализованы только в заголовочном файле? )

1 голос
/ 18 мая 2019

Когда вы определяете параметр как auto, компилятор будет использовать шаблоны в фоновом режиме:

Ваша функция:

std::string stringify(const auto& arr, const std::string& ch);

равна:

template<class T>
std::string stringify(const T& arr, const std::string& ch);

И функции шаблона должны быть определены (не только объявлены).Таким образом, опция заключается в том, чтобы определить его в заголовочном файле.

...