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++;_C++_Templates_Template Meta Programming - Fatal编程技术网

C++ 如何在C++;

C++ 如何在C++;,c++,templates,template-meta-programming,C++,Templates,Template Meta Programming,我正在尝试为实现编写一个通用的static\u,它可以接受边界,一个递增函数和一个比较函数来运行循环。我一直在使用这个结构,简单的循环递增1。在这种情况下,只需专门指定IDX&END相等,就可以很容易地停止循环展开 但是,当增量可以是任意整数时,不能保证IDX&END始终相等。仅在运行时计算if条件。在下面的代码片段中,我试图专门研究停止递归的std::false\u类型。积分_常数是通过计算std::less函数(用户可将其替换为任何其他计算)来构造的。不幸的是,这个比较器函数也只在运行时进行

我正在尝试为实现编写一个通用的static\u,它可以接受边界,一个递增函数和一个比较函数来运行循环。我一直在使用这个结构,简单的循环递增1。在这种情况下,只需专门指定
IDX&END
相等,就可以很容易地停止循环展开

但是,当增量可以是任意整数时,不能保证
IDX&END
始终相等。仅在运行时计算
if
条件。在下面的代码片段中,我试图专门研究停止递归的
std::false\u类型。积分_常数是通过计算
std::less
函数(用户可将其替换为任何其他计算)来构造的。不幸的是,这个
比较器
函数也只在运行时进行评估,因此编译器失败。有人能建议一下如何让它工作吗

注意:使用C++11

template <int idx, int end, typename eval, int count, typename comparator>
struct static_for_loop {
  template <typename Lambda, typename... Args>
  void operator()(const Lambda& function, Args... args) const {
    if (comparator()(idx, end)) {
      std::integral_constant<int, idx> i;

      function(i, args...);

      constexpr bool lesser = comparator()(idx + count, end);
      static_for_loop<idx + count, end, std::integral_constant<bool, lesser>, count,
                      comparator>()(function, args...);
    }
  }
};

template <int idx, int end, int count, typename comparator>
struct static_for_loop<idx, end, std::false_type, count, comparator> {
  template <typename Lambda, typename... Args>
  void operator()(const Lambda& function, Args... args) const {}
};

template <int idx, int end, int count = 1, typename comparator = std::less<int>>
struct static_for {
  template <typename Lambda, typename... Args>
  void operator()(const Lambda& function, Args... args) const {
    static_for_loop<idx, end, std::true_type, count, comparator>()(function, args...);
  }
};
模板
用于循环的结构静态\u{
模板
void运算符()(常量Lambda和函数,Args…Args)常量{
if(比较器()(idx,end)){
std::积分常数i;
功能(i,args…);
constexpr bool lesser=比较器()(idx+计数,结束);
静态_for_loop()(函数,参数…);
}
}
};
模板
用于循环的结构静态\u{
模板
void运算符()(常量Lambda&function,Args…Args)常量{}
};
模板
结构静态{
模板
void运算符()(常量Lambda和函数,Args…Args)常量{
静态_for_loop()(函数,参数…);
}
};

我发现将所有内容包装在一个对象中更容易:

template <int S, int E, int step>
struct iter {
    auto next() { return iter<std::min(E, S+step), E, step>{}; }
};

你喜欢哪一种

您可以使用sfinae来解决此问题:

template <int idx, int end, typename eval, int count, typename Comparator>
struct static_for_loop {
    template <typename Lambda, typename... Args>
    auto operator()(Lambda&& function, Args&&... args) const
    -> std::enable_if_t<Comparator{}(idx, end)> {
        std::integral_constant<int, idx> i;

        std::forward<Lambda>(function)(i, std::forward<Args>(args)...);

        constexpr bool lesser = comparator{}(idx + count, end);

        static_for_loop<
            idx + count,
            END,
            std::integral_constant<bool, lesser>,
            count,
            Comparator
        >()(std::forward<Lambda>(function), std::forward<Args>(args)...);
    }

    // do nothing when false
    template <typename Lambda, typename... Args>
    auto operator()(Lambda&& function, Args&&... args) const
    -> std::enable_if_t<!Comparator{}(idx, end)> {

    }
};
模板
用于循环的结构静态\u{
模板
自动运算符()
->std::如果启用,则启用{
std::积分常数i;
std::forward(函数)(i,std::forward(args)…);
constexpr bool lesser=比较器{}(idx+计数,结束);
静态循环<
idx+计数,
完,,
std::积分_常数,
计数
比较器
>()(std::forward(函数),std::forward(args)…);
}
//做错了事
模板
自动运算符()
->std::如果启用,则启用{
}
};
std::enable_如果
将使用sfinae选择正确的功能。如果需要,它将充当编译时

我也使用了完美转发,因为您的代码在所有情况下都不起作用,比如传递不可复制或可变的lambda。现在会了

如果没有c++14,则可以编写
typename std::enable\u If::type


尽量少用大写字母,这会影响易读性。

问题不在于您没有充分指定比较器
?只要指定API,使
comparator::type
std::true\u type
,如果循环应继续
IDX
,并在
false\u type
时停止。然后,您的简单循环用例使用Comp=std::integral\u常量的
模板

对不起,我忘了添加我仍在使用C++11。这对于使用通用lambdas的C++14来说是一个很好的解决方案。@AmmarHusain您实际上不需要C++14来完成任何操作,只是一些方便的速记。是的,如果启用,则可以工作。我现在要试一试。我无法编译你建议的代码。它的enable_if用法有问题。以下是我从clang中得到的信息:“std::enable_if';”中没有名为“type”的类型如果不能使用“启用”,则启用\udeclaration@AmmarHusain不知道你的意思。这是一个在C++11中运行的程序。我无法编译您建议的代码。它的enable_if用法有问题。以下是我从clang中得到的信息:“std::enable_if';”中没有名为“type”的类型enable_if'不能用于禁用此声明请尝试更新编译器。请注意,您应该同时提供这两个函数,其中一个带有
在启用if中,一个不启用。
// prints 0 4 8
for_loop(iter<0, 10, 4>{}, [](int i){std::cout << i << ' ';});   
template <int S, int E, int step, class F, class... Args>
std::enable_if_t<(S<E)> for_loop(iter<S, E, step>, F func, Args... args)
{
    func(S, args...);
    for_loop(iter<S+step, E, step>{}, func, args...);
}

template <int S, int E, int step, class F, class... Args>
std::enable_if_t<!(S<E)> for_loop(iter<S, E, step>, F , Args... )
{
}
template <int idx, int end, typename eval, int count, typename Comparator>
struct static_for_loop {
    template <typename Lambda, typename... Args>
    auto operator()(Lambda&& function, Args&&... args) const
    -> std::enable_if_t<Comparator{}(idx, end)> {
        std::integral_constant<int, idx> i;

        std::forward<Lambda>(function)(i, std::forward<Args>(args)...);

        constexpr bool lesser = comparator{}(idx + count, end);

        static_for_loop<
            idx + count,
            END,
            std::integral_constant<bool, lesser>,
            count,
            Comparator
        >()(std::forward<Lambda>(function), std::forward<Args>(args)...);
    }

    // do nothing when false
    template <typename Lambda, typename... Args>
    auto operator()(Lambda&& function, Args&&... args) const
    -> std::enable_if_t<!Comparator{}(idx, end)> {

    }
};