C++ 编译器如何传递'std::initializer_list'值?(或者:我怎样才能用一个解决通用过载问题?)

C++ 编译器如何传递'std::initializer_list'值?(或者:我怎样才能用一个解决通用过载问题?),c++,c++11,overloading,variadic-functions,initializer-list,C++,C++11,Overloading,Variadic Functions,Initializer List,,我意识到我可以使用单个std::initializer\u 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"

,我意识到我可以使用单个
std::initializer\u 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 */ }
    //...
};
(因为我不能根据初始值设定项列表中的条目数量来更改类型,因为它是运行时的,所以我修复了返回类型并在条目数量错误时抛出。)新重载的代码很长,我必须对
mutable
const
版本重复它,所以我想知道如何保存代码。我试图搞乱
const\u 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;
    //...
};
类数组 { //... my_类型和运算符[](尺寸_类型i); 我的类型常量和运算符[](大小类型i)常量; my_类型和运算符[](标准::初始值设定项_列表i) { 返回常量强制转换(常量强制转换与通用方法冲突)

TL;DR:示例代码显示函数参数列表中按值获取的
std::initializer\u list
对象。这是编译器传递它们时的第一个首选项吗?还是通过引用?如果需要精确匹配(以克服通用重载),这一点很重要。

消歧转换:

int     f( int );
double  f( double );

template < typename Func, typename ...Args >
void  do_it( Func &&f, Args &&...a );

//...

int  main( int, char *[] )
{
    do_it( (double(*)(double))&f, 5.4 );
    return 0;
}

(我的灵感来自于回答别人的帖子,需要区分函数模板重载。)它需要几次尝试,尤其是不必创建中间对象。

注意:内部
常量转换
是不必要的,因为总是允许添加
常量
,如
数组\u md const&me=*this;
@MatthieuM。实际上,有必要驱动重载解析。否则,非常量运算符将尽管这个问题写得很好,但我觉得你错过了编写代码自包含模拟的关键步骤(以及你正在使用的编译器,加上你得到的确切信息有时会有所帮助)。因为我可以复制它,它被GCC 4.8接受并按预期运行(即,删除的重载不会被触发)。@Angew:不,它不是…如果我写的时候你创建一个常量引用并调用
()
在const引用上。@MatthieuM.对。我误解了您的const ref代码只是一个不需要强制转换的示例。当然,通过
me
调用将减少对
const\u强制转换的需要。
。由于消歧调用在成员函数的签名中包括
const
-模式,我可以切换到一个没有
const
的空“
this
”-首先对它进行限定(我的
操作符[]
的示例不能,因为它的
const
限定符是导致重载解析的原因。)
int     f( int );
double  f( double );

template < typename Func, typename ...Args >
void  do_it( Func &&f, Args &&...a );

//...

int  main( int, char *[] )
{
    do_it( (double(*)(double))&f, 5.4 );
    return 0;
}
class array_md
{
    //...
    template < typename ...Index >
    complicated &        at( Index &&...i );  // (1)

    template < typename ...Index >
    complicated const &  at( Index &&...i ) const;  // (2)

    my_type &            at( std::initializer_list<size_type> i )  // (3)
    {
        return const_cast<my_type &>(
          (
            const_cast<array_md const *>( this )
            ->*
            static_cast<
              my_type const &
              (array_md::*)
              ( std::initializer_list<size_type> ) const
            >( &array_md::at )
          )( i )
        );
    }

    my_type const &      at( std::initializer_list<size_type> i ) const;  // (4)
    //...
};