Jak zrobić krotkę stałych referencji?
Powiedz, że są dwie funkcje:
void ff( const std::tuple<const int&> ) { }
template < typename TT >
void gg( const std::tuple<const TT&> ) { }
i wzywa do tych funkcji:
int xx = 0;
ff( std::tie( xx ) ); // passes
gg( std::tie( xx ) ); // FAILS !!
GCC 4.7.2 nie potrafi skompilować ostatniej linii i zgłasza komunikat o błędzie, taki jak:
note: template argument deduction/substitution failed:
note: types ‘const TT’ and ‘int’ have incompatible cv-qualifiers
note: ‘std::tuple<int&>’ is not derived from ‘std::tuple<const TT&>’
Pierwsze pytanie brzmi, czy pasuje to do standardu C ++ 11, a jeśli nie, to dlaczego?
Ponadto, aby rozwiązać ten problem, należy przekazać krotkę stałych odniesień dogg
zamiast przekazywać krotkę nie-stałych odniesień (którestd::tie
sprawia). Można to zrobić przez:
gg( std::tie( std::cref(x) ) );
jednak dodatkowe wezwanie dostd::cref
jest nudny, więc byłoby wspaniale mieć coś takiegoctie
który tworzy krotkę stałych referencji.
Drugie pytanie dotyczy tego, czy istnieje potrzeba napisaniactie
ręcznie, a jeśli tak, to czy jest to najlepszy sposób, aby to zrobić?
template < typename... T >
std::tuple<const T&...> ctie( const T&... args )
{
return std::tie( args... );
}