如何使用SFINAE解决重载函数中的歧义

jaymmer-恢复莫妮卡

我有一个令人难以置信的令人兴奋的库,它可以翻译点:它可以与任何点类型一起使用

template<class T>
auto translate_point(T &p, int x, int y) -> decltype(p.x, p.y, void())
{
    p.x += x;
    p.y += y;
}

template<class T>
auto translate_point(T &p, int x, int y) -> decltype(p[0], void())
{
    p[0] += x;
    p[1] += y;
}

translate_point将与具有publicxymember的点一起使用,并且还将xy分别由第一个元素和第二个元素表示的元组/可索引容器一起工作

问题是,另一个库使用publicx定义了一个点类y,但是还允许建立索引:

struct StupidPoint
{
    int x, y;

    int operator[](int i) const
    {
        if(i == 0) return x;
        else if(i == 1) return y;
        else throw "you're terrible";
    }

};

使用两个库的我的应用程序如下:

int main(int argc, char **argv)
{
    StupidPoint stupid { 8, 3 };
    translate_point(stupid, 5, 2);
    return EXIT_SUCCESS;
}

但这使GCC(和叮当声)感到不满:

error: call of overloaded ‘translate_point(StupidPoint&, int, int)’ is ambiguous

现在,我知道了为什么会发生这种情况,但是我想知道如何解决此问题(假设我无法更改StupidPoint的内部结构),并且,如果没有简单的解决方法,作为库实现者,我将如何使这一过程变得更容易处理。

天顶

如果要优先考虑使用public x/的情况y,则可以执行以下操作:

template<class T>
auto translate_point_impl(int, T &p, int x, int y) -> decltype(p.x, p.y, void())
{
    p.x += x;
    p.y += y;
}

template<class T>
auto translate_point_impl(char, T &p, int x, int y) -> decltype(p[0], void())
{
    p[0] += x;
    p[1] += y;
}

template<class T>
void translate_point(T &p, int x, int y) {
    translate_point_impl(0, p, x, y);
}

不用说,相反的配置是通过切换第一个参数的类型给出的。


如果您具有三个或更多选项(例如N),则可以使用基于模板的技巧。
这是上面切换到这种结构后的示例:

template<std::size_t N>
struct choice: choice<N-1> {};

template<>
struct choice<0> {};

template<class T>
auto translate_point_impl(choice<1>, T &p, int x, int y) -> decltype(p.x, p.y, void()) {
    p.x += x; p.y += y;
}

template<class T>
auto translate_point_impl(choice<0>, T &p, int x, int y) -> decltype(p[0], void()) {
    p[0] += x;
    p[1] += y;
}

template<class T>
void translate_point(T &p, int x, int y) {
    // use choice<N> as first argument
    translate_point_impl(choice<1>{}, p, x, y);
}

如您所见,现在N可以采用任何值。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何使用SFINAE解决重载函数中的歧义

来自分类Dev

如何解决以下代码中的函数重载歧义

来自分类Dev

解决重载函数的歧义

来自分类Dev

使用SFINAE解决过载歧义

来自分类Dev

使用SFINAE解决过载歧义

来自分类Dev

如何解决“ fpclassify”:对重载函数的歧义调用

来自分类Dev

如何解决方法引用中的重载歧义?

来自分类Dev

如何消除重载函数的歧义

来自分类Dev

使用SFINAE的“重载”构造函数

来自分类Dev

如何解决传递给Boost线程的函数中的歧义

来自分类Dev

对基类中的重载函数的歧义调用

来自分类Dev

C ++与Java中函数重载的歧义

来自分类Dev

重载函数的歧义

来自分类Dev

如何解决对重载定义的歧义引用

来自分类Dev

VS2013中使用可变参数模板时“对重载函数的歧义调用”

来自分类Dev

在VS2013中使用可变参数模板时“对重载函数的歧义调用”

来自分类Dev

由于std :: function而在构造函数重载中存在歧义

来自分类Dev

由于std :: function而在构造函数重载中存在歧义

来自分类Dev

如何解决我的GADT中的歧义

来自分类Dev

如何解决cucumberjs中的歧义问题?

来自分类Dev

使用概念进行函数重载解析(而不是SFINAE)

来自分类Dev

如何转换重载的自由函数来解决重载冲突?

来自分类Dev

SFINAE和重载函数的地址

来自分类Dev

函数继承中的函数重载歧义,其中函数具有相同数量的参数

来自分类Dev

非捕获lambda和函数指针作为重载函数歧义中的参数

来自分类Dev

可变参数模板函数中对重载函数的歧义调用

来自分类Dev

对重载整数构造函数的歧义调用

来自分类Dev

模板编程:对重载函数的歧义调用

来自分类Dev

如何使用可选参数重载TypeScript中的函数?

Related 相关文章

热门标签

归档