2016-12-15 63 views
1

所以我有一个类:模板参数包不能推断`常量&`参数

struct C { 
    int x[10]; 

    int const& get(int i) const { return x[i]; } 

    template<typename... Ts> 
    auto& get(Ts... args) { 
    int const& (C::*f)(Ts...) const = &C::get; 
    return const_cast<int&>((this->*f)(args...)); 
    } 
}; 

和模板将根据需要生成非const吸气,所以这成为法律:

int& test(C& c) { 
    int i = 4; 
    int& r = c.get(i); 
    return r; 
} 

但如果我改变了原来的getter的参数类型的引用:

int const& get(int const& i) const { return x[i]; } 

const获得者模板不能与const获得者匹配。

很明显,通过价值传递int并没有什么大不了的,把参数列表明确地传递给模板并没有什么大不了的,但是我有更复杂的参数和大量的重载,并且我想推断我所有的非参数, const getters具有最低限度的复制粘贴。

有什么办法可以过去吗?


我想过了,我可以在类内声明的问题,参数列表,但留下的定义模板,这样的说法匹配将有一定的指导意义。我试过(之前或之后的模板)添加以下的类:

int& get(int const& i); 

不幸的是这完全绕过了模板和链接错误的结果。向声明中添加inlinetemplate似乎也无法解决问题。

+0

通过“无数重载”事实证明,我其实有两个,但它是我关心的_principle_。我可能会晚一些。 – sh1

+0

我认为你的编译器应该抱怨'int&i = c.get(i)',因为'int&'不是const。 –

+0

@Anders K.,这就是模板存在的原因。它通过调用const getter并从结果中剥离const来创建一个非const的getter。这对于从各种const和非const方法中使用相同的getter很有用。如果存在很多重载,那么它会选择具有与该调用相匹配的参数列表的那个。不幸的是,如果const getter采用引用参数,则“匹配”失败,因为该调用看起来像是按值调用。 – sh1

回答

2

为什么通过辅助指针指向成员函数来强制执行const成员函数的调用?在这种情况下,我使用const资格this

template<typename... Ts> 
auto& get(Ts... args) { 
    const C* const const_this = this; 
    return const_cast<int&>(const_this->get(args...)); 
} 
+0

哦,哎呀!因为它是从另一个模板演化而来的,我尝试在返回类型上获得隐式匹配。 – sh1

+0

这确实使代码工作(所以它回答了我的问题);但我为什么不清楚。一个替代版本,它接受一个函数指针参数,以便大部分的措辞可以应用于各种getter,仍然受到影响。 – sh1

相关问题