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++ 我可以更改通用变量lambda的模板参数推断顺序吗?_C++_Templates_Variadic Templates_C++20_Generic Lambda - Fatal编程技术网

C++ 我可以更改通用变量lambda的模板参数推断顺序吗?

C++ 我可以更改通用变量lambda的模板参数推断顺序吗?,c++,templates,variadic-templates,c++20,generic-lambda,C++,Templates,Variadic Templates,C++20,Generic Lambda,以下面的代码为例,这是一个简化的示例: 模板 无效foo(F){ //bool some=is_variadic_v;//场景#1 bool some=true;//场景2 f(int(some),int(some)); } int main(){ 自动部分=[](int i,int j){ std::cout“编译器现在是否将sizeof…(params)同时推断为2和13”两者!但不是同时。它验证(“实例化”是正确的词)两种情况下的lambda体(即,对于尝试调用lambda的每一组参数类型

以下面的代码为例,这是一个简化的示例:

模板
无效foo(F){
//bool some=is_variadic_v;//场景#1
bool some=true;//场景2
f(int(some),int(some));
}
int main(){
自动部分=[](int i,int j){

std::cout“编译器现在是否将sizeof…(params)同时推断为2和13”两者!但不是同时。它验证(“实例化”是正确的词)两种情况下的lambda体(即,对于尝试调用lambda的每一组参数类型)。我有XY问题的感觉。为什么你需要知道lambda是否是可变的?@HolyBlackCat这听起来很奇妙,同时对我来说也很可怕。在通常的SFINAE中,只有当实例化在返回类型或(模板)中产生错误时,它才会删除重载候选项根据你的理论,如果我添加static_assert(2==sizeof…(params));在cout之前,它仍然应该编译,对吗?但它不是!有一点我不明白。@HolyBlackCat关于XY:我有一个函数,它将实例化编译时循环N次,N是传递函数的算术数。如果该函数是可变的,我假设一个最大可感循环计数,它通常不等于我认为函数是“可变的”,这是相当令人困惑的,因为你正在谈论两个不同版本的代码,似乎重要的部分不包括在这个问题中。链接可能腐烂,也链接到其他的问题/答案。如果答案被编辑了呢?请在你的问题中包含所有的代码。“编译器现在是否将sizeof…(params)同时推断为2和13”都是!但不是同时。它验证(“实例化”是正确的词)两种情况下的lambda体(即,对于您尝试调用lambda的每一组参数类型)。我有XY问题的感觉。为什么你需要知道lambda是否是可变的?@HolyBlackCat这听起来很奇妙,同时对我来说也很可怕。在通常的SFINAE中,只有当实例化在返回类型或(模板)中产生错误时,它才会删除重载候选项根据你的理论,如果我添加static_assert(2==sizeof…(params));在cout之前,它仍然应该编译,对吗?但它不是!有一点我不明白。@HolyBlackCat关于XY:我有一个函数,它将实例化编译时循环N次,N是传递函数的算术数。如果该函数是可变的,我假设一个最大可感循环计数,它通常不等于我认为函数是“可变的”,这是相当令人困惑的,因为你正在谈论两个不同版本的代码,似乎重要的部分不包括在这个问题中。链接可能腐烂,也链接到其他的问题/答案。如果答案被编辑了呢?请在你的问题中包含所有的代码。
#include <utility>
#include <type_traits>
#include <iostream>

constexpr int max_arity = 12; // if a function takes more arguments than that, it will be considered variadic

struct variadic_type { };

// it is templated, to be able to create a
// "sequence" of arbitrary_t's of given size and
// hence, to 'simulate' an arbitrary function signature.
template <auto>
struct arbitrary_type {
    // this type casts implicitly to anything,
    // thus, it can represent an arbitrary type.
    template <typename T>
    operator T&&();

    template <typename T>
    operator T&();
};

template <
    typename F, auto ...Ints,
    typename = decltype(std::declval<F>()(arbitrary_type<Ints>{ }...))
>
constexpr auto test_signature(std::index_sequence<Ints...> s) {
    return std::integral_constant<int, size(s)>{ };
}

template <auto I, typename F>
constexpr auto arity_impl(int) -> decltype(test_signature<F>(std::make_index_sequence<I>{ })) {
    return { };
}

template <auto I, typename F, typename = std::enable_if_t<(I > 0)>>
constexpr auto arity_impl(...) {
    // try the int overload which will only work,
    // if F takes I-1 arguments. Otherwise this
    // overload will be selected and we'll try it 
    // with one element less.
    return arity_impl<I - 1, F>(0);
}

template <typename F, auto MaxArity>
constexpr auto arity_impl() {
    // start checking function signatures with max_arity + 1 elements
    constexpr auto tmp = arity_impl<MaxArity+1, F>(0);
    if constexpr (tmp == MaxArity+1) 
        return variadic_type{ }; // if that works, F is considered variadic
    else return tmp; // if not, tmp will be the correct arity of F
}

template <typename F, auto MaxArity = max_arity>
constexpr auto arity(F&&) { return arity_impl<std::decay_t<F>, MaxArity>(); }

template <typename F, auto MaxArity = max_arity>
constexpr auto arity_v = arity_impl<std::decay_t<F>, MaxArity>();

template <typename F, auto MaxArity = max_arity>
constexpr bool is_variadic_v = std::is_same_v<std::decay_t<decltype(arity_v<F, MaxArity>)>, variadic_type>;

template <typename F>
void foo(F f) {
    bool some = is_variadic_v<F>;
    //bool some = true;
    f(int(some), int(some));
}

int main() {
    auto some = [](int i, int j) {
        std::cout << i << " " << j << '\n';
    };
    
    foo([&some](auto... params) {
        some(params...);
    });
}
foo([&some](auto... params) {
    // int foo = std::index_sequence<sizeof...(params)>{ };
    std::cout << sizeof...(params) << '\n';
});
error: cannot convert 'std::index_sequence<13>' {aka 'std::integer_sequence<long unsigned int, 13>'} to 'int' in initialization
   85 |         int foo = std::index_sequence<sizeof...(params)>{ };