Я видел этот вопрос .
Кажется, что вне зависимости от приведения временный объект (ы) будет «выживать» до тех пор, пока не будет оценена полная экспрессия.
Но по следующему сценарию:
template<class T>
struct bar {
T t;
bar(T t) : t(t) {}
template<class U>
bar(bar<U> other) : t(other.t) {}
};
void foo(bar<const double&> b) {
printf("%lf\n", b.t);
}
int main() {
foo(bar<const double&>(2));//#1
foo(bar<int>(2)); //#2
return 0;
}
1 работает хорошо, а 2 - нет.
И MSVC дал мне предупреждение о 2: «Ссылочный элемент инициализируется как временный, который не сохраняется после выхода из конструктора»
Теперь мне интересно, почему они оба создают временный double
объект и передают его bar<const double&>
, и только 2 не удалось.
@ обновление
Я использую struct bar вместо boost::tuple
в исходном посте, надеюсь, он станет более знакомым для других.
Позвольте мне прояснить мой вопрос. В # 1 из int
(2) создается временное double
, а затем из него создается bar<const double &>
и копируется в foo
, в то время как в # 2 создается временное bar<int>
и временное double
создается из члена bar<int>
в ctor bar<const double&>
. Кажется, что временное double
разрушено в foo
в # 2, а не в # 1. Зачем? Я думаю, что все они являются частью фуллэкспрессии и будут существовать до bar
возвращения.
Тим говорит: "Компилятор достаточно умен, чтобы рассматривать эти 2 как двойные вместо целых." поэтому я написал int i = 2;
и передал i
обоим вызовам, но все идет как прежде. Я сделал это в VS2008 с режимом отладки.