C++11变长参数函数默认参数值

5

我有一个包装器,可以多次调用模板函数:

template <std::uint16_t N, typename F, typename  ... Args>
inline typename std::result_of<F && (Args &&...)>::type retry_n(F && f, Args&& ... ax)
{
    for (auto i = 0; i < N; ++i)
    {
        try
        {
            return std::forward<F>(f)(std::forward<Args>(ax)...);
        }
        catch (const some_except &e){ /*ignore exception for a while*/ }
    }
    throw;//re-raise
}

在我传递默认参数函数之前,所有东西都正常工作:

int f(int a, int b, int c = 5);
.... 
retry_n<10>(f, 1, 2); // error C2198: 'bla-bla' : too few arguments for call

如何允许默认参数在不显式指定的情况下使用?

retry_fn<10>([](auto...x){return f(x...);}, 1, 2) - Johannes Schaub - litb
@ᐅJohannesSchaub-litbᐊ 是的,这是一个清晰的解决方法。 - Dewfy
1个回答

2
默认参数不是函数签名的一部分,也不参与模板类型推断。因此,每当您将 f 传递给 retry_n<> 时,F 的类型被推断为 int(int, int, int),因此本地的 f 是后者类型,并且默认参数已经被排除在外了。您唯一的解决方案是直接使用要测试的函数,而不是让它的类型被推断,就像 @Johannes Schaub - litb 的评论中所说的那样,或者,如果您的编译器不支持通用 lambda (C++14),则将其包装成具有可变模板 operator() 的函数对象。
struct functor
{
    template<typename... T>
    int operator()(T&&... params)
    {
        return f(std::forward<T>(params)...);
    }  
};

使用它作为

retry_n<10>(functor{}, 1, 2);

感谢您提供技术上正确的答案。我在 https://dev59.com/ZYbca4cB1Zd3GeqPV3FM#27687037 上查看了一下,有一些感觉 std::enable_if_t 可以应用在那里。 - Dewfy
@Dewfy 嗯,可能是这样,请在找到解决方案后发布答案,这个问题很有趣。 - vsoftco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接