Скажем, есть две функции:
void ff( const std::tuple<const int&> ) { }
template < typename TT >
void gg( const std::tuple<const TT&> ) { }
и вызывает следующие функции:
int xx = 0;
ff( std::tie( xx ) ); // passes
gg( std::tie( xx ) ); // FAILS !!
GCC 4.7.2 не может скомпилировать последнюю строку и сообщает об ошибке, например:
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&>’
Первый вопрос: если это соответствует стандарту С++ 11, а если нет, то почему?
Кроме того, для преодоления этой проблемы необходимо передать кортеж ссылок const на gg
вместо передачи набора неконстантных ссылок (что делает std::tie
). Это можно сделать:
gg( std::tie( std::cref(x) ) );
однако дополнительный вызов std::cref
является довольно утомительным, поэтому было бы здорово иметь что-то вроде ctie
, которое создавало бы кортеж ссылок const.
Второй вопрос: нужно ли писать ctie
вручную, и если да, то это лучший способ сделать это?
template < typename... T >
std::tuple<const T&...> ctie( const T&... args )
{
return std::tie( args... );
}