【问题标题】:Can this code that expands integer parameter pack be written with just 1 function?这个扩展整数参数包的代码可以只用 1 个函数编写吗?
【发布时间】:2017-05-25 20:12:37
【问题描述】:

我的代码使用折叠表达式将函数参数与类模板的整数参数进行比较。 代码工作 AFAIK,但我想知道是否可以在没有 _impl 辅助函数的情况下做我想做的事情。

完整代码(我的问题是contains是否可以在没有contains_impl的情况下实现):

#include <algorithm>
#include <iostream>
#include <utility>
#include <cstdlib>
#include <tuple>

template <int H, int... T>
class if_set {
    private:
    template<typename... Ts>
    bool contains_impl(const int& val, Ts... ts) const{
        return (false || ... || (val == ts));
    }    
    public:
    bool contains(const int& val) const {
        return contains_impl( val, H, T...);
    }
};

using namespace std;
int main()
{
    constexpr if_set<1,3,4,5> isi;
    for (int i = -1; i < 10; ++i) {
        cout << i << ": " << boolalpha << isi.contains(i) << endl;
    }
    if_set<'a','e','i','o','u', 'A', 'E', 'I', 'O', 'U'>  vowels;
    string word = "ARCADE FIRE: Modern man";
    cout << word << endl;
    word.erase(remove_if(word.begin(), word.end(), [&vowels](const char& c){return vowels.contains (c);}), word.end());
    cout << word << endl;
}

注 1:我知道这段代码有很多问题,我不打算在生产中使用它,我不鼓励人们直接使用它或作为灵感,这是我在阅读有趣的article 后想实现的一个玩具示例关于冻结的 C++ 库。

注意 2:false || 看起来很丑,但 IDK 有更好的方式。

【问题讨论】:

  • 为什么不return (val == H) || (... || val == T);
  • 因为一些奇怪的错误:prog.cc: In member function 'bool if_set::contains(const int&) const': prog.cc:17:38: error: operand of fold 表达式没有未展开的参数包 return (val == H) || (... || val == T);

标签: c++ template-meta-programming c++17 fold-expression


【解决方案1】:

是的,你可以做到:

template <int H, int... T>
class if_set {
public:
    bool contains(const int& val) const {
        return ((val == H) || ... || (val == T));
    }
};

或者,您也可以在 std::integer_sequences 上工作:

template<typename T1, typename T2, T1... Is>
bool contains(std::integer_sequence<T1, Is...>, T2 val) {
    return (... || (val == Is)); // perhaps should be (false || ... || (val == Is)), but this appears to work
}

【讨论】:

  • 啊,我需要额外的 () 围绕 (val == H) || ... || (val == T).. 并且错误消息非常无用... :/ 只是另一个有趣的 C++ 功能。你知道为什么需要 () 吗?
  • @NoSenseEtAl 因为折叠表达式需要用括号括起来。 (... || Bools) 有效,而 ... || Bools 无效。至于原因,我猜是因为这样更容易确定折叠表达式的确切位置。
  • 根据cppreference,表达式的规则是“在顶层不包含优先级低于强制转换的运算符” A == 低于强制转换。这么多括号,但你应该可以做!(val == T) &amp;&amp; ...f(val, T) || ...good[T] || ...等。另外,你不能做template &lt;int... T&gt; blah blah return ((val ==T) || ...);吗?即,为什么有H
猜你喜欢
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 2011-11-18
  • 2017-02-01
  • 2020-12-10
  • 2022-01-04
  • 1970-01-01
相关资源
最近更新 更多