括号内的参数包扩展会产生奇怪的输出

Geo*_*zes 4 c++ variadic-templates c++11

我正在尝试实现一个接受可变数量的字符串并转发到print函数的函数,该函数需要char指针和size每个字符串交错.

例:

std::string a = "123";
std::string b = "1234";
forward(a, b); // should call doPrint(a.c_str(), a.size(), b.c_str(), b.size())
Run Code Online (Sandbox Code Playgroud)

我认为以下应该是一个正确的实现,但即使它编译行为是非常令我惊讶的.

template <class ...Args>
void forward(const Args & ... args) {
  doPrint( (args.c_str(), args.size())...);
}
Run Code Online (Sandbox Code Playgroud)

forward(a, b)打电话doPrint(3, 4),而不是doPrint("123", 3, "1234", 4),就像我写的那样doPrint((args.size())...).c_str()编译器完全忽略调用.

我试过g++,clang并且icc所有产生相同的输出.有什么问题(args.c_str(), args.size())...

确实,std::make_tuple(args.c_str(), args.size())...按预期工作,但是我要说我不能改变doPrint接受和处理元组.

Sir*_*Guy 7

逗号运算符是一个表达式,其值是最后一个表达式的值.
例如:

    int a = (1, 2, 3, 4, 5, 6);
    assert(a == 6);
Run Code Online (Sandbox Code Playgroud)

您可以尝试使用元组:

    doPrint(std::tuple_cat(std::make_tuple(argc.c_str(), args.size())...));
Run Code Online (Sandbox Code Playgroud)

然后doPrint需要更改为使用元组; 如果需要,它可以将元组解压缩回参数包,或者直接使用元组.

解压缩元组的示例:

    template <class Tuple, std::size_t ... indices>
    doPrint(Tuple t, std::integer_sequence<size_t, indices...>)
    {
        doPrint(std::get<indices>(t)...);
    }

    template <class Tuple>
    doPrint(Tuple t)
    {
        doPrint(t, std::make_index_sequence<std::tuple_size<Tuple>::value>());
    }
Run Code Online (Sandbox Code Playgroud)

模糊函数名称可能存在一些问题,因此您可能需要更改这些辅助函数的名称,但希望这足以让您继续使用.


Mat*_* F. 5

(args.c_str(), args.size())是一个以逗号分隔的表达式,这意味着只有最后一个part(args.size())将被传递给该函数.

然后它将为每个参数重复此操作,因此它实际上doPrint只会调用字符串大小!

你应该doPrint改为使用元组,否则你必须使用一些疯狂的模板元编程的东西.