Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用省略号的回退功能:我们可以强制参数包的大小吗?_C++_Templates_Sfinae_Variadic Functions - Fatal编程技术网

C++ 使用省略号的回退功能:我们可以强制参数包的大小吗?

C++ 使用省略号的回退功能:我们可以强制参数包的大小吗?,c++,templates,sfinae,variadic-functions,C++,Templates,Sfinae,Variadic Functions,考虑以下代码: #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

考虑以下代码:

#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(A&&…args)->decltype(std::declval().f(std::forward(args)…),void()){

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

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)); }
};
结构{
私人:
模板
自动f_impl(A&&…参数)
->decltype(std::declval().f(std::forward)

您可以使用一个函数(assert)获取指向函数的指针来推断参数的大小:

#include <utility>
#include <iostream>
template <typename...Args>
struct size_assert{
    template <typename T,typename R,typename... Params>
    constexpr static bool assert(R(T::*)(Params...) )
    {
        static_assert(sizeof...(Args) == sizeof...(Params),"Incorrect size of arguments!");
        return true;
    }
};

struct S {

    template<typename T, typename... A, bool =  size_assert<A...>::assert(&T::f)>
    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() {
   // std::cout <<fc(&f);
    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)
}
#包括
#包括
模板
结构大小断言{
模板
constexpr静态布尔断言(R(T::*)(Params…)
{
静态断言(sizeof…(Args)==sizeof…(Params),“参数大小不正确!”;
返回true;
}
};
结构{
模板
自动f(A&&…args)->decltype(std::declval().f(std::forward(args)…),void())
{

std::cout…并在该层中检查参数包的大小,对吧。它是有效的,但我想知道是否存在一种不需要我定义新函数的解决方案。目前,我直接在f中修复了参数计数。如果创建一个traits,您可以使用2变量方法,并使用SFINAE检查大小。这与我在l中所做的不完全相同我正在寻找答案,但它可以工作。谢谢。我说的是这样的:正如我所说的,这不完全是我想要的,但如果你在答案中添加代码,我会接受答案……你到底为什么需要这个?有人会认为强迫最终用户传递伪参数是糟糕的API设计。@T.C.很公平。我正在尝试一些一位同事提出了疑问。只是好奇,这不是针对生产软件的。真正的问题更大,不适合发布更好的示例。
当省略号以这种方式涉及时,有没有办法强制参数的数量?
:不,没有。可变参数只有
va_start
va_end
,以及
va_列表
操作。
#include <utility>
#include <iostream>
template <typename...Args>
struct size_assert{
    template <typename T,typename R,typename... Params>
    constexpr static bool assert(R(T::*)(Params...) )
    {
        static_assert(sizeof...(Args) == sizeof...(Params),"Incorrect size of arguments!");
        return true;
    }
};

struct S {

    template<typename T, typename... A, bool =  size_assert<A...>::assert(&T::f)>
    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() {
   // std::cout <<fc(&f);
    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)
}