Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.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++_C++17_Fold Expression - Fatal编程技术网

C++ c++;具有用户定义类的折叠表达式

C++ c++;具有用户定义类的折叠表达式,c++,c++17,fold-expression,C++,C++17,Fold Expression,我想创建一个包含多个参数的日志函数,我还想用我的类调用日志函数。 这是我的代码(编译器:Visual studio 2019或x86-64 gcc9.2) 问题1>我无法理解日志函数。 可以这样使用折叠表达式吗? (此函数来自spdlog库) 问题2> 如何在Mystruct类中使用log函数? log(1,MyStruct(1,1.1f,“你好世界”);//编译器错误 #include <cstdio> #include <iostream> #include <

我想创建一个包含多个参数的日志函数,我还想用我的类调用日志函数。
这是我的代码(编译器:Visual studio 2019或x86-64 gcc9.2)

问题1>我无法理解日志函数。 可以这样使用折叠表达式吗? (此函数来自spdlog库)

问题2> 如何在Mystruct类中使用log函数?
log(1,MyStruct(1,1.1f,“你好世界”);//编译器错误

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

template<typename ... Args>
void log(int level, Args const& ... args)
{
    std::ostringstream stream;
    using List = int[];
    (void)List {
        0, ((void)(stream << args), 0) ...
    };
    std::cout << stream.str() << std::endl;
}

class MyStruct
{
public:
    int val1 = 0;
    float val2 = 0.f;
    std::string val3;

    MyStruct(int v1, float v2, std::string_view const& v3) : val1(v1), val2(v2), val3(v3) {};
    std::string to_string() const
    {
        std::stringstream stream;
        stream << "val1=" << val1 << ", val2=" << val2 << ",val3=" << val3;
        return stream.str();
    }
};

std::ostringstream& operator<< (std::ostringstream& stream, MyStruct&& val)
{
    auto str = val.to_string();
    std::operator <<(stream, str);
    return stream;
}

void work_good()
{
    using namespace std::string_literals;  
    log(1, 1.1f, "hello world"s);
}

void compile_error()
{
    using namespace std::string_literals;  
    log(1, MyStruct(1, 1.1f, "hello world"s));
}

int main()
{
    work_good();
}
#包括
#包括
#包括
#包括
模板
无效日志(整数级,参数常量和…参数)
{
std::奥斯汀溪流;
使用List=int[];
(作废)名单{
0,((无效)(流)
问题1>我无法理解日志函数。是否可以使用
像这样的表情

确切地说,它没有使用(从C++17开始)。请参阅,这是C++11支持的,是的,它在
log
中的有效用法

一个模式后跟一个省略号,其中至少有一个参数包的名称至少出现一次,该模式被扩展为零个或多个以逗号分隔的模式实例化,其中参数包的名称依次替换为包中的每个元素

问题2>我如何在Mystruct类中使用log函数


您声明了
操作符我更改了一些代码引用的答案。
我希望日志函数更通用

namespace nlog
{
    class MyStruct
    {
    public:
        int val1 = 0;
        float val2 = 0.f;
        std::string val3;

        MyStruct(int v1, float v2, std::string_view const& v3) : val1(v1), val2(v2), val3(v3) {};
        std::string to_string() const
        {
            std::stringstream stream;
            stream << "val1=" << val1 << ", val2=" << val2 << ",val3=" << val3;
            return stream.str();
        }
    };

    template < typename T, typename decltype(std::declval<T>().to_string())* = nullptr>
        std::ostream& operator<< (std::ostream& stream, T&& val)
    {
        auto str = val.to_string();
        std::operator <<(stream, str);
        return stream;
    }


    template <typename ... Ts>
    void tolog(Ts && ...args)
    {
        std::stringstream strbuf;
        (strbuf << ... << std::forward<Ts>(args));

        std::cout << strbuf.str() << std::endl;
    }

    template <typename ... Ts>
    void toout(Ts && ...args)
    {
        (std::cout << ... << args);
    }
};

namespace nlog
{
    void Test1()
    {
        using namespace std::string_literals;
        std::stringstream strbuf;
        strbuf << MyStruct(0, 0.1f, "Eric"s);
        std::cout << strbuf.str() << std::endl;
    }

    void Test2()
    {
        using namespace std::string_literals;
        tolog(1, 1.1f, "hello world"s);
    }

    void Test3()
    {
        using namespace std::string_literals;
        tolog("I like this func val=", 100, ", youvalue=", 1.0f, ", MyStruct=",  MyStruct(0, 0.1f, "Eric"s));
    }
};

int main()
{
    nlog::Test1();
    nlog::Test2();
    nlog::Test3();
}
名称空间nlog
{
类MyStruct
{
公众:
int val1=0;
float val2=0.f;
std::字符串val3;
MyStruct(intv1,floatv2,std::string_view const&v3):val1(v1),val2(v2),val3(v3){};
std::string to_string()常量
{
std::stringstream;

stream@eerorika你能解释一下吗?我试过OP的代码,它可以在C++17之前的模式下编译。真的吗?我可能会感到困惑。@eerorika我认为应用了折叠表达式,但没有。请注意来自Clang的警告。我没有意识到逗号运算符甚至可以用于包扩展。我只见过带argumen的包扩展t列表。很高兴知道。@songyuanyao谢谢,你是对的,我成功地构建了这个代码lol。此外,我还修复了一个更通用的代码YC++17倍表达式:
((流)
namespace nlog
{
    class MyStruct
    {
    public:
        int val1 = 0;
        float val2 = 0.f;
        std::string val3;

        MyStruct(int v1, float v2, std::string_view const& v3) : val1(v1), val2(v2), val3(v3) {};
        std::string to_string() const
        {
            std::stringstream stream;
            stream << "val1=" << val1 << ", val2=" << val2 << ",val3=" << val3;
            return stream.str();
        }
    };

    template < typename T, typename decltype(std::declval<T>().to_string())* = nullptr>
        std::ostream& operator<< (std::ostream& stream, T&& val)
    {
        auto str = val.to_string();
        std::operator <<(stream, str);
        return stream;
    }


    template <typename ... Ts>
    void tolog(Ts && ...args)
    {
        std::stringstream strbuf;
        (strbuf << ... << std::forward<Ts>(args));

        std::cout << strbuf.str() << std::endl;
    }

    template <typename ... Ts>
    void toout(Ts && ...args)
    {
        (std::cout << ... << args);
    }
};

namespace nlog
{
    void Test1()
    {
        using namespace std::string_literals;
        std::stringstream strbuf;
        strbuf << MyStruct(0, 0.1f, "Eric"s);
        std::cout << strbuf.str() << std::endl;
    }

    void Test2()
    {
        using namespace std::string_literals;
        tolog(1, 1.1f, "hello world"s);
    }

    void Test3()
    {
        using namespace std::string_literals;
        tolog("I like this func val=", 100, ", youvalue=", 1.0f, ", MyStruct=",  MyStruct(0, 0.1f, "Eric"s));
    }
};

int main()
{
    nlog::Test1();
    nlog::Test2();
    nlog::Test3();
}