加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 使用省略号的后退功能:我们可以强制参数包的大小吗?

发布时间:2020-12-16 07:17:20 所属栏目:百科 来源:网络整理
导读:请考虑以下代码: #include utility#include iostreamstruct S { templatetypename T,typename... A auto f(A... args) - decltype(std::declvalT().f(std::forwardA(args)...),void()) { std::cout "has f(int)" std::endl; } templatetypename void f(...)
请考虑以下代码:

#include <utility>
#include <iostream>

struct S {
    template<typename T,typename... A>
    auto f(A&&... args) -> decltype(std::declval<T>().f(std::forward<A>(args)...),void()) {
        std::cout << "has f(int)" << std::endl;
    }

    template<typename>
    void f(...) {
        std::cout << "has not f(int)" << std::endl;
    }
};

struct T { void f(int) { } };
struct U { };

int main() {
    S s;
    s.f<T>(42); // -> has f(int)
    s.f<U>(42); // -> has not f(int)
    // oops
    s.f<T>(); // -> has not f(int)
}

如示例所示,对f的第三次调用工作得很好,即使参数的数量是错误的,因为它对于回退函数完全没有错.

当省略号以这种方式涉及时,有没有办法强制参数的数量?
我的意思是,我可以在编译时检查参数列表的大小是否正好为1,无论是选择主函数还是后备函数?

良好的解决方案也只涉及第一个模板功能,并且由于参数包的大小而导致硬错误而不是软错误.

当然,它可以通过几种技术解决,而无需使用可变参数.举个例子:int / char调度内部模板方法;显式指定参数列表;随你…
问题不是关于做到这一点的替代方法,我已经知道了.
这只是要知道我是否遗漏了一些基本的东西,或者这是不可能的,这就是全部.

解决方法

如果我正确理解您的问题,您可以添加一个图层:

struct S {
private:
    template<typename T,typename... A>
    auto f_impl(A&&... args)
    -> decltype(std::declval<T>().f(std::forward<A>(args)...),void()) {
        std::cout << "has f(int)" << std::endl;
    }

    template<typename>
    void f_impl(...) {
        std::cout << "has not f(int)" << std::endl;
    }
public:

    template<typename T,typename A>
    auto f(A&& args) { return f_impl<T>(std::forward<A>(arg)); }
};

有了特质,你可以这样做

template <typename T,typename ... Ts>
using f_t = decltype(std::declval<T>().f(std::declval<Ts>()...));

template <typename T,typename ... Ts>
using has_f = is_detected<f_t,T,Ts...>;

struct S {
    template<typename T,typename... A>
    std::enable_if_t<has_f<T,A&&...>::value && sizeof...(A) == 1> f(A&&... args)
    {
        std::cout << "has f(int)" << std::endl;
    }

    template<typename T,typename... A>
    std::enable_if_t<!has_f<T,A&&...>::value && sizeof...(A) == 1>  f(A&&... args) {
        std::cout << "has not f(int)" << std::endl;
    }
};

Demo

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读