gpt4 book ai didi

c++ - 使用省略号的回退函数 : can we force the size of the parameters pack?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:15:20 26 4
gpt4 key购买 nike

考虑以下代码:

#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,无论选择的是 main 函数还是 fallback?

好的解决方案也是那些只涉及第一个模板函数并且由于参数包的大小而导致硬错误而不是软错误的解决方案。


当然,它可以在不使用可变参数的情况下使用多种技术来解决。例如: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

关于c++ - 使用省略号的回退函数 : can we force the size of the parameters pack?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39207003/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com