继续我的传奇,我意识到我可以使用单个std::initializer_list
参数来重载我的访问函数:
class array_md
{
//...
my_type & operator []( size_type i )
{ /* Lots of code */ }
my_type const & operator []( size_type i ) const
{ /* same Lots of code, with "const" sprinkled in */ }
my_type & operator []( std::initializer_list<size_type> i )
{ /* Lots of different code */ }
my_type const & operator []( std::initializer_list<size_type> i ) const
{ /* same Lots of different code, with "const" sprinkled in */ }
//...
};
对于我的版本,at
我现在有:
class array_md
{
//...
template < typename ...Index >
complicated & at( Index &&...i ) // (1)
{ /* Lots of code */ }
template < typename ...Index >
complicated const & at( Index &&...i ) const // (2)
{ /* same Lots of code, with "const" sprinkled in */ }
my_type & at( std::initializer_list<size_type> i ) // (3)
{ /* Lots of different code */ }
my_type const & at( std::initializer_list<size_type> i ) const // (4)
{ /* same Lots of different code, with "const" sprinkled in */ }
//...
};
(由于我不能根据初始化列表中的条目数量来更改类型,因为它是运行时的,所以我修复了返回类型并在条目数量错误时抛出。)新重载的代码是很长,我必须为mutable
和const
版本重复它,所以我想知道如何保存代码。我试图弄乱const_cast
:
class array_md
{
//...
my_type & operator []( size_type i );
my_type const & operator []( size_type i ) const;
my_type & operator []( std::initializer_list<size_type> i )
{
return const_cast<my_type &>( const_cast<array_md const
*>(this)->operator [](i) );
}
my_type const & operator []( std::initializer_list<size_type> i ) const;
//...
};
这里第三个版本调用第四个版本,const_cast
用来解决编译器的抱怨。(侵入是可以的,因为我const
从一开始就打它的东西剥离。不要颠倒依赖关系;你最终可能会mutable
在一个真正的const
对象上调用一个成员函数!)我试图做同样的事情at
,用标记为 (4) 的过载实现标记为 (3) 的过载。但是,由于 有 3 个替代项at
,因此我得到了与 (2) 被选中相关的错误!与通用重载相比,我如何将 传递std::initializer_list
给内部at
调用(按值)不会导致完全匹配?我是普遍方法冲突的老朋友。
TL;DR:示例代码显示std::initializer_list
在函数参数列表中按值获取的对象。这是编译器传递它们的第一选择吗?还是通过引用代替?如果您需要精确匹配(以克服通用重载),这一点很重要。