Automati c Построение объекта в параметрах функции путем передачи параметров конструктора - PullRequest
0 голосов
/ 22 марта 2020

Можете ли вы объяснить, почему следующий код компилируется и запускается? Какова здесь концепция, и каковы ограничения / требования для такой методологии для работы?

class string_wrapper
{
public:
    string_wrapper(string i_string);

    string m_value;
    int m_length;
};

string_wrapper::string_wrapper(string i_string)
{
    m_value = i_string;
    m_length = i_string.length();
}

void bar(string_wrapper i_param)
{
    cout << i_param.m_value << std::endl;
}

void foo()
{
    string test_string = "test1";

    bar(test_string);
}

int main()
{
    test_function_b();
}

Вывод:

test1

Я ожидаю, что этот код не скомпилируется , foo () передает строковый параметр в bar (), когда bar принимает только параметр string_wrapper. Однако компилятор достаточно умен, чтобы знать, что он может использовать строковый параметр в качестве параметра для конструктора объекта string_parameter, который, вероятно, затем передается в качестве фактического параметра в bar ().

Это поведение в стандарте C ++ или уникальное для моего компилятора (в данном случае Visual Studio 2017, версия 15.9)? Буду признателен за любые идеи или терминологию, которые я смогу использовать для дальнейших исследований.

1 Ответ

0 голосов
/ 22 марта 2020

Здесь происходит неявная конструкция . Вы правы в том, что компилятор достаточно «умен», чтобы знать, что вы можете создать string_wrapper из std::string, и это делает это автоматически для вас.

Чтобы остановить это, вы можете использовать * Ключевое слово 1007 * вроде этого:

...
explicit string_wrapper(string i_string);
...

Ключевое слово explicit сообщает компилятору, что вы не хотите, чтобы оно автоматически создавало string_wrapper объекты для вас из std::string. Это может помешать отслеживать ошибки, поскольку предотвращает случайное создание объектов (особенно при возврате функции и при передаче аргументов).

Неявное построение может происходить, когда у объекта есть только один не заданный по умолчанию параметр (неявное преобразование - это то, что вы также должны исследовать). Это может быть мощным инструментом и может разрешать такие вещи, как прокси-классы и прозрачные API (т.е. ссылочный класс std::vector). Как правило, вы должны объявлять конструкторы с одним параметром (или с одним значением по умолчанию) (и операторы преобразования) explicit, если вы не принимаете проектное решение не слишком.

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