【问题标题】:c++17 fold expression syntatxc++17折叠表达式语法
【发布时间】:2018-07-19 13:47:09
【问题描述】:

我在第 18 行和第 23 行遇到了折叠表达式的代码工作问题

我想让它有这样的结果

"1 2 3 4"
"9 0 -1 -200"
"abc"
" world"
"Empty List"

如果列表是空的,你会打印"Empty List",如果不是,如果类型是char,它不会打印空间,如果类型不是char,它会打印中间的空间。

我尝试使用((std::cout<<" " << list), ...);,但它会打印我不想要的额外空间,因此我将其存储在临时字符串中,然后将其删除。

有人可以帮忙吗?

#include <iostream>
#include <string>
template<int ... intlist>
using IntList = typename Facility<int>::List<intlist...>;

template<char ... charlist>
using CharList = typename Facility<char>::List<charlist...>;

template<short ... shortlist>
using ShortList = typename Facility<short>::List<shortlist...>;

template<unsigned short ... shortlist>
using UnsignedShortList = typename Facility<unsigned short>::List<shortlist...>;

template<long ... list>
using LongList = typename Facility<long>::List<list...>;

template<typename T , typename Comp=std::less<T>>
struct Facility
{
  template<T ... list> 
  struct List
  {
    static void print()
    {
      std::string str; 
      str ="\"";
      if(sizeof...(list)== 0)
      {
         str+="Empty List";
      }
      else if (std::is_same<T, char>::value)
      {
        str+=(... + list);
         //((std::cout<< list), ...);
      }
      else
      {
        str+=((" " + list), ...);
        //((std::cout<<" " << list), ...);
        str.erase(0,1);
      }
      str+="\"";
      std::cout << str << std::endl;
    }  
  }; 
};

int main()
{
    using List1 = IntList<1,2,3,4>;
    using List2 = IntList<9, 0, -1, -200>;
    List1::print();
    List2::print();

    using String1 = CharList<'a', 'b', 'c'>;
    using String2 = CharList<' ', 'w', 'o', 'r', 'l', 'd' >;
    using EmptyString = CharList<>;
    String1::print();
    String2::print();
    EmptyString::print();

  }

【问题讨论】:

  • 帮助什么?真正的问题是什么?
  • 能否提供调用代码。
  • 你好,我想用折叠表达式代替 cout 参数包,我想存储到 str 并编辑然后 cout
  • 是的,我忘记了,对不起
  • str+=(... + list) 不会做你所期望的。附加单个字符,它是所有 char 值的总和(截断为 char)。

标签: c++ c++17 fold-expression


【解决方案1】:

据我了解,您可能会使用:

template<typename T>
struct Facility
{
    template <T ... list>
    struct List
    {
        static void print()
        {
            std::cout << '"';
            if constexpr (sizeof...(list) == 0)
            {
                 std::cout << "Empty List";
            }
            else if constexpr (std::is_same<T, char>::value)
            {
                ((std::cout << list), ...);
            }
            else
            {
                [[maybe_unused]]  const char* sep = "";
                (((std::cout << sep << list), sep = " "), ...);
            }
            std::cout << '"' << std::endl;
        }  
    }; 
};

有用法:

int main() {
    Facility<int>::List<>::print();
    Facility<int>::List<42, 42>::print();
    Facility<char>::List<'h', 'e', 'l', 'l', 'o'>::print();
}

Demo

【讨论】:

  • 谢谢 我从来没想过在逗号后面设置空格
  • 它在 C++17 中相当于 for versionidioms-for-joining display
  • 我注意到使用这种方法在性能方面存在问题,如果有 20,000 个元素,它编译速度很慢
  • 那么,你可以试试static const T args[] = {list...}; 并使用for循环版本。
  • LOL 这些就是编码员所说的模因。非常有趣。谢谢你们俩。
【解决方案2】:

另一种解决方案可能是使用std::ostringstream 并删除最后一个字符(将空格放在最后一个位置)

    std::ostringstream oss;

    ((oss << list << ' '), ...);

    str += oss.str().substr(0, oss.str().size()-1);

以下是完整的编译示例

#include <string>
#include <iostream>
#include <sstream>

template<typename T , typename Comp=std::less<T>>
struct Facility
{
  template<T ... list> 
  struct List
  {
    static void print()
    {
      std::string str;

      str = "\"";

      if(sizeof...(list)== 0)
      {
         str += "Empty List";
      }
      else if (std::is_same<T, char>::value)
      {
        std::ostringstream oss;

        ((oss << list), ...);

        str += oss.str();
      }
      else
      {
        std::ostringstream oss;

        ((oss << list << ' '), ...);

        str += oss.str().substr(0, oss.str().size()-1);
      }

      str += "\"";

      std::cout << str << std::endl;
    }  
  }; 
};

int main ()
{
  Facility<int>::List<1, 2, 3, 4> f;

  f.print();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-21
    • 2020-01-25
    • 2020-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多