2015-11-30 5 views
3

Если я называю «func (const generic & ref)» с целым числом как аргументом (вместо «общего» объекта), конструктор generic (int _a) будет для создания нового объекта.Литерал C++, переданный в const ссылается на автоматическое построение

class generic { 
public: 
    int a; 
    generic() {} 
    generic(int _a) : a(_a) { 
     std::cout << "int constructor was called!"; 
    } 
    generic(const generic& in) : a(in.a) { 
     std::cout << "copy constructor was called!"; 
    } 
}; 

void func(const generic& ref) { 
    std::cout << ref.a; 
} 

int main() { 
    generic g(2); 
    func(g); // this is good. 
    func(generic(4)); // this is good. 
    func(8); // this is good...... ? 
    return 0; 
} 

Последний вызов func (8) создает новый объект с использованием конструктора generic (int _a). Есть ли название для такого рода строительства? Должен ли программист явно конструировать объект перед передачей аргумента? Например:

func(generic(8)); 

Есть ли какой-либо выгоды при передаче целого числа (кроме экономии времени)?

+0

http://en.cppreference.com/w/cpp/language/implicit_cast – szczurcio

+1

У вас есть конструктор, который принимает 'int', поэтому компилятор будет использовать его для создания« generic ». Если вы хотите, чтобы он не использовал этот конструктор, используйте ключевое слово 'explicit '. –

ответ

4

Данное поведение является частью процесса overload resolution - в частности.

Когда вы вызываете func(), компилятор строит список кандидатов. Есть только один кандидат, func(const generic& ref), поэтому компилятор пытается выяснить, как сделать звонок.

Он видит, что нет func(int), поэтому он пытается найти путь преобразования от int до generic. Поскольку существует конструктор generic, который принимает int, и нет других преобразований, позволяющих выполнять один и тот же вызов, компилятор принимает конструкцию + путь вызова.

Компилятор проверяет три вещи, в порядке от высшего к низшему приоритету:

  • Точное совпадение
  • Promotion
  • Conversion

Это означает, что точное соответствие подписи выигрывает матч, требующий поощрения, и матч, который требует, чтобы козыри поощрения соответствовали требованиям, требующим конверсии.

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

3

Есть ли название для такого строительства? Должен ли программист явно конструировать объект перед передачей аргумента?

Если вы не хотите, чтобы это произошло, вы можете добавить explicit specifier в конструкторе:

explicit generic(int _a) : a(_a) 
{ 
    std::cout << "int constructor was called!"; 
} 

отрывок из страницы cppreference:

конструктор, который объявлен без спецификатора функции explicit называется конструктором преобразования.

По умолчанию в этом случае допускаются неявные вызовы конструктора.

Есть ли какое-либо преимущество при передаче целого числа (кроме экономии времени)?

ли вы вызвать метод с func(8) или func(generic(8)) не собирается изменить то, что код выполняет данный код, который вы написали. Если бы вы добавили перегрузку func, которая принимает int вместо generic, тогда вызовы внезапно станут разными. Итак, хотя это, в конечном счете, вопрос мнения, я думаю, что вам лучше быть явным, используя func(generic(8)).

 Смежные вопросы

  • Нет связанных вопросов^_^