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的第三次调用工作得很好,即使参数的数量是错误的,因为它对于回退函数完全没有错. 当省略号以这种方式涉及时,有没有办法强制参数的数量? 良好的解决方案也只涉及第一个模板功能,并且由于参数包的大小而导致硬错误而不是软错误. 当然,它可以通过几种技术解决,而无需使用可变参数.举个例子: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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |