C ++ 11 шаблонная специализация с пустым типом и аргументом - PullRequest
0 голосов
/ 05 ноября 2019

В программе C ++ 11 я определяю эти шаблоны:

namespace outcome {

template <class T>
class c_out {
    public:
        bool success = false;
        std::string error = "";
        T result;
};

template <class T>
c_out<T> failed(T res, const std::string& error_msg = "") {
    c_out<T> outcome;
    outcome.success = false;
    outcome.error = error_msg;
    return outcome;
};

template <class T>
c_out<T> succeeded(T res) {
    c_out<T> outcome;
    outcome.success = true;
    outcome.result = res;
    return outcome;
};

};

Я хочу специализировать их, когда class T равен void. Это легко работает для c_out :

template <>
class c_out<void> {
    public:
        bool success = false;
        std::string error = "";
};

Однако я продолжаю получать ошибки для двух других функций. Как я могу специализировать их?

c_out<void> failed(const std::string& error_msg = "") {
    c_out<void> outcome;
    outcome.success = false;
    outcome.error = error_msg;
    return outcome;
};

c_out<void> succeeded(void) {
    c_out<void> outcome;
    outcome.success = true;
    return outcome;
};

Ошибки : Когда я звоню

outcome::succeeded();

в YYY.cpp , я получаю ошибки связываниябиблиотека:

lib/libXXX.a(YYY.cpp.o): In function `outcome::failed(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
YYY.cpp:(.text+0x0): multiple definition of `outcome::failed(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
CMakeFiles/ZZZ.dir/main/main.cpp.o:main.cpp:(.text+0x0): first defined here
lib/libXXX.a(YYY.cpp.o): In function `outcome::succeeded()':
YYY.cpp:(.text+0x50): multiple definition of `outcome::succeeded()'
CMakeFiles/ZZZ.dir/main/main.cpp.o:main.cpp:(.text+0x50): first defined here

Ответы [ 2 ]

0 голосов
/ 05 ноября 2019

Это не специализации. Это перегрузки. И это обычные функции, что важно, потому что специализации шаблонов функций по умолчанию имеют несколько свойств, которых нет у обычных функций.

Например, шаблоны могут появляться в заголовке и поэтому могут быть определены в несколькихперевод единиц без проблем. Шаблоны неявно встроены . Обычные функции должны быть явно встроены.

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

Решение состоит в том, чтобы либо переместить эти перегрузки в выделенный TU, и открытьтолько их декларации. Или вы можете пометить их как встроенные в заголовке:

inline c_out<void> failed(const std::string& error_msg = "") {
    c_out<void> outcome;
    outcome.success = false;
    outcome.error = error_msg;
    return outcome;
};

inline c_out<void> succeeded(void) {
    c_out<void> outcome;
    outcome.success = true;
    return outcome;
};

Это выложит встроенное определение в каждом TU. Пока все определения одинаковы (что верно для функции в заголовке), программа будет правильно сформирована.

0 голосов
/ 05 ноября 2019

1.Пожалуйста, убедитесь, что вы не используете разные файлы при компиляции. Например, если у вас есть шаблонный класс в заголовочном файле, а основной - в другом .cpp-файле, который может вызвать сбой программы, так как при поиске шаблона в .cpp-файле, как в приведенном выше случае, не существует. Это может быть причиной проблемы.

В некоторых IDE такой проблемы нет, поэтому вы можете попробовать другую IDE и проверить, появляется ли такая же ошибка.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...