Можно ли взять параметр по ссылке на константу, при этом запретив преобразования, чтобы вместо этого не передавались временные параметры?

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

Вызов bar в этом коде завершается ошибкой. Это желательно, потому что ссылка неправильного типа. Вызов bar_const также имеет неправильный тип, но компилируется без уведомления. Для меня это нежелательно.

#include
using namespace std;

int vi;

void foo(int &) { }
void bar(long &) { }
void bar_const(const long &) { }

int main() {
   foo(vi);
   // bar(vi); // compiler error, as expected/desired
   bar_const(vi);
}

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

(Очевидно, int и long - очень маленькие типы. Но я был пойман с более крупными структурами, которые можно преобразовать друг в друга. Я не хочу, чтобы это тихо происходит, когда я беру ссылку на константу.Иногда пометка конструкторов как явных помогает, но это не идеально)

Обновление: Я представляю себе такую ​​систему: представьте себе две функции X byVal (); и X & byRef (); и следующий блок кода:

 X x;
 const_lvalue_ref a = x; // I want this to compile
 const_lvalue_ref b = byVal(); // I want this to fail at compile time
 const_lvalue_ref c = byRef(); // I want this to compile

Этот пример основан на локальных переменных, но я хочу, чтобы он также работал с параметрами. Я хочу получить какое-то сообщение об ошибке, если я случайно передаю ссылку на временную или ссылку на копию, когда думаю, что передаю что-то легкое, например, ссылку на lvalue. Это просто «стандарт кодирования» - если я действительно хочу разрешить передачу ссылки во временную, я буду использовать простую const X & . (Я нахожу этот фрагмент на FOREACH от Boost как весьма полезный.)

5
задан Aaron McDaid 31 January 2012 в 16:21
поделиться