14

假设有两个功能:

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... );
}
4

1 回答 1

4

第一个问题是这是否符合 C++11 标准,如果不符合,那为什么呢?

这是预期的行为。在第二种情况下,模板参数推导失败,因为没有T所以tuple<const T&>变成tuple<int&>.

在第一种情况下,它可以工作,因为它可以tuple<int&>隐式转换为tuple<const int&>. 这是用户定义的转换,因此在模板参数推导过程中不考虑。

你的问题闻起来有点像 X/Y 问题。考虑发布让您寻找涉及这种函数模板/元组组合的解决方案的真正问题。

您的ctie函数模板看起来不错。但请记住,像

auto t = ctie(5);

基本上会产生一个悬空的参考。因此,您可能只想限制ctie为左值。

于 2013-08-22T11:23:20.927 回答