使用SFINAE解决过载歧义 [英] Resolve overload ambiguity with SFINAE

查看:77
本文介绍了使用SFINAE解决过载歧义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了类似的情况,但是他们通常最终按照我在这里所做的事情来做。(

I've found similar cases, but they usually ended up doing something along the lines of what I (think) I'm doing here.

我想能够调用带有一个或多个参数的函数,显然,如果该函数存在多个参数的重载,那么没有帮助就无法得出正确的版本。

I want to be able to call a function with one or more parameters, obviously, if the function exists with overloads with multiple parameters, the correct version cannot be deduced without help.

我还指定了参数个数,因此我认为对于编译器来说,这足以得出正确的重载信息。
似乎并非如此,我希望您可以向我展示原因。

As I am specifying the number of arguments as well, I figured this would be enough information for the compiler to deduce the correct overload. This doesn't seem to be the case and I hope you may be able to show me why.

代码:
http://coliru.stacked-crooked.com/a/5e6fd8d5418eee3c

#include <iostream>
#include <type_traits>
#include <functional>

template < typename R, typename... A, typename... Args >
typename std::enable_if< sizeof...( A ) == sizeof...( Args ), R >::type
call_my_function( R(*func)(A...), Args ...a )
{
    return func( a... );
}

int arg_count() { return 0; }
int arg_count(int) { return 1; }
int arg_count(int,int) { return 2; }

int main()
{
    std::cout << call_my_function( arg_count, 0 ) << std::endl;
    return 0;
}

简而言之,我试图让所有函数的参数计数与我提供的参数数量通过SFINAE失败。

In short, I tried to have all functions which have a different argument count than the number of arguments I supplied, fail by means of SFINAE. But it seems they are considered anyway and the ambiguity remains.

推荐答案

不幸的是,还没有。 SFINAE可用于在不同的函数模板定义之间进行选择,但不能在作为参数传递的函数重载之间进行选择。

Unfortunately not; SFINAE can be used for selecting between different function template definitions, but not between function overloads passed as an argument.

这是因为必须解析作为参数传递的重载函数到单个重载,然后对模板函数定义中的依赖类型进行评估并加入SFINAE。

This is because an overloaded function passed as an argument must be resolved to a single overload before dependent types in the template function definition are evaluated and SFINAE kicks in.

您可以通过创建 n 重载模板定义,其中 n-1 是要处理的最大参数个数:

You can see this by creating n overloaded template definitions, where n - 1 is the maximum number of arguments you want to handle:

template < typename R, typename... Args >
typename std::enable_if< 0 == sizeof...( Args ), R >::type
call_my_function( R(*func)(), Args ...a )
{
    return func( a... );
}

template < typename R, typename A1, typename... Args >
typename std::enable_if< 1 == sizeof...( Args ), R >::type
call_my_function( R(*func)(A1), Args ...a )
{
    return func( a... );
}

template < typename R, typename A1, typename A2, typename... Args >
typename std::enable_if< 2 == sizeof...( Args ), R >::type
call_my_function( R(*func)(A1, A2), Args ...a )
{
    return func( a... );
}

此处每个 arg_count 只能解析为一个 call_my_function 定义,因此在特定的 call_my_function 定义内对于哪个<$ c $没有歧义c> arg_count 已通过。

Here each arg_count resolves to exactly one call_my_function definition, so there is no ambiguity within a particular call_my_function definition as to which arg_count was passed.

可能的解决方案是生成这些 n 手动或使用预处理器(例如使用Boost.Preprocessor)重载。

A possible solution would be to generate these n overloads either manually or using the preprocessor (e.g. using Boost.Preprocessor).

这篇关于使用SFINAE解决过载歧义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆