шаблоны — перегруженный оператор c ++ против обычного аргумента

у меня есть шаблон функции (C ++)

template<typename T>
void print_to_default_file(T &obj, ADDON addon = "")

и перегруженная функция

template<typename T>
void print_to_default_file(T &obj, std::string  objS) // or char* objS

Класс ADDON имеет перегрузку оператора следующей подписи

void operator=(const std::string)

Проблема в том, что когда я делаю
print_to_default_file («тест», «куда я пойду»)

Звонит первый, но я хочу позвонить второй. Я устал от char * вместо std :: string, но результат тот же.

Может ли кто-нибудь, пожалуйста, указать, что не так

ADDON упрощенная версия

class ADDON {
std::string s;

public:
ADDON() {
s = "";
}

ADDON(std::string in) {
s = in;
}

ADDON(const char in[]) {
s = in;
}

void operator=(const std::string in) {
s = in;
}

std::string getString() {
return s;
}
};

2

Решение

Ваш оригинальный код не компилируется

Код, который вы нам показали

#include <iostream>
#include <string>

class ADDON {
std::string s;

public:
ADDON() {
s = "";
}

ADDON(std::string in) {
s = in;
}

ADDON(const char in[]) {
s = in;
}

void operator=(const std::string in) {
s = in;
}

std::string getString() {
return s;
}
};

template<typename T>
void print_to_default_file(T &obj, ADDON addon = "")
{ std::cout << "first overload\n"; }

template<typename T>
void print_to_default_file(T &obj, std::string  objS)
{ std::cout << "second overload\n"; }

int main()
{
print_to_default_file("test","where will I go");
}

не компилируется (онлайн выход) со следующей ошибкой

prog.cpp: в функции int main (): prog.cpp: 39: 52: ошибка: вызов
перегружен файл «print_to_default_file (const char [5], const char [16])»
неоднозначный prog.cpp: 39: 52: примечание: кандидаты: prog.cpp: 30: 6: примечание:
void print_to_default_file (T&, ADDON) [с T = const char [5]] prog.cpp: 34: 6: примечание: void print_to_default_file (T&, std :: string) [с
T = const char [5]; std :: string = std :: basic_string]

Причина в том, что поиск имени и вывод аргумента находят 2 кандидата: первая перегрузка требует const char* в ADDON преобразование, а вторая перегрузка const char* в std::string преобразование. Обе последовательности преобразования одинаково хорошо соответствуют друг другу, а восстановление при перегрузке неоднозначно, а ваша программа некорректна.

Простое исправление

Просто измените вторую перегрузку, чтобы принять const char* как параметр (а не как char*, который не может связываться со строковыми литералами), и это будет лучшим совпадением для необработанных строковых литералов в качестве аргумента

template<typename T>
void print_to_default_file(T &obj, const char*  objS) // but NOT char* objS
{ std::cout << "second overload\n"; }

Теперь вы получите вторую перегрузку (онлайн выход). Чтобы выбрать первую перегрузку, просто вызовите ADDON конструктор в списке параметров

int main()
{
print_to_default_file("test", ADDON("where will I go"));
}

Обратите внимание, что это вызовет ADDON(const char[]) конструктор, а не ADDON(std::string) один, так как последний потребует пользовательского преобразования (онлайн выход).

Правильное исправление

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

class ADDON {
std::string s;

public:
ADDON() {
s = "";
}

explicit ADDON(std::string in) {
s = in;
}

explicit ADDON(const char in[]) {
s = in;
}

void operator=(const std::string in) {
s = in;
}

std::string getString() {
return s;
}
};

Это также вызовет вторую перегрузку (онлайн выход), поскольку ADDON Перегрузка не вызывает явно конструктор. Чтобы выбрать первую перегрузку, снова вызовите ADDON конструктор в списке параметров.

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]