假设有两个功能:
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&>’
第一个问题是,如果这符合C ++ 11标准,如果不符合,那么为什么呢?
此外,要克服此问题,需要将const引用的元组传递给gg
,而不是传递非const引用的元组(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... );
}
答案 0 :(得分:3)
第一个问题是,如果这符合C ++ 11标准,如果不符合,那么为什么呢?
这是预期的行为。在第二种情况下,模板参数推断失败,因为没有T
,因此tuple<const T&>
变为tuple<int&>
。
在第一种情况下,它有效,因为tuple<int&>
可以隐式转换为tuple<const int&>
。这是用户定义的转换,因此在模板参数推断期间不予考虑。
你的问题有点像X / Y问题。考虑发布真实问题,让您寻找涉及此类函数模板/元组组合的解决方案。
您的ctie
功能模板看起来很好。但请记住像
auto t = ctie(5);
基本上会产生一个悬空参考。因此,可能只想将ctie
限制为左值。