std::make_tuple不接受列表初始化对象的参数是否有原因?

#include <string>
#include <map>
#include <cstdint>

class FileInfo
{
public:
    FileInfo() = default;
    FileInfo(const std::string &name, uint64_t size) : mName(name), mSize(size) { }

    bool operator == (const FileInfo& other) const
    {
        return mName == other.mName;
    }

private:
    std::string mName;
    uint64_t mSize = 0;
};

void function(FileInfo fileInfo) { }

using Modifications = std::map<std::string, std::tuple<std::string, FileInfo, FileInfo>>;

int main(int argc, char *argv[])
{
    Modifications modifications{
        { "f1", std::make_tuple("changed", FileInfo{ "f1", 1 }, FileInfo{ "f1", 2 }) },
        { "f2", std::make_tuple("removed", FileInfo{ "f2", 1 }, FileInfo{}) },
        { "f3", std::make_tuple("added", FileInfo{}, { "f3", 2 }) } // Error
    };

    function({ "f3", 2 }); // OK

    return 0;
}


地图中的第三对给出以下错误:


  错误C2660'std :: make_tuple':函数未使用3个参数


这个错误对我来说毫无意义。当我明确声明std::make_tuple的类型为Modifications时,为什么std::map<std::string, std::tuple<std::string, FileInfo, FileInfo>>不接受第三个参数?是否存在编译器限制,或者只是标准中忽略了这一限制?

注意:此问题与从括号列表构造元组无关:initialize-an-stdarray-of-tuples-with-curly-braces

最佳答案

正如注释中指出的那样,错误在于您没有在调用FileInfo函数的过程中构造make_tuple对象,C ++编译器无法知道您希望第三个对象是什么。如果您将通话更改为这样的话

std::make_tuple<std::string, FileInfo, FileInfo>("added", FileInfo{}, { "f3", 2 })


然后代码也将起作用,您需要make_tuple函数能够推断出参数列表中事物的类型。

The compiler cannot deduce the type of an initializer list in a template argument

关于c++ - 将列表初始化的对象传递给std::make_tuple,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41372739/

10-16 20:46