Chr*_*000 5 c++ templates variadic c++11
我想将调用转发到具有可变方法的库.我能提出来复制问题的最简单的例子是:
void Bar(int useless, ...)
{
//Does something
}
template<typename... Args>
void Foo(int useless, Args... args)
{
Bar(useless, args...);
}
Run Code Online (Sandbox Code Playgroud)
如你所见,我已经去了.但是,即使这个编译,它似乎导致堆栈有一个摇摆,我看到应用程序退出时出错.从编译器的角度来看,我可以理解这个解决方案存在问题.
我不确定如何使这个工作,或者是否有可能让这个工作.我看到有些人建议在类似情况下使用"索引技巧",但我无法在这个特殊场合使用它.
任何帮助赞赏!
小智 9
你采取的方法本身是非常理智,安全和健全的.例如,下面的程序使用可变参数模板参数并将它们转发给std::printf(),这是一个接受可变数量参数的C风格函数:
#include <utility>
#include <cstdio>
template <unsigned int S, typename ...T>
void my_printf(const char (&fmt)[S], T&&... args) {
std::printf(fmt, std::forward<T>(args)...);
}
int main(int argc, const char* argv[]) {
my_printf("Hello, %s!\n", "World!");
my_printf("I will count to %u...\n", 10);
for (int i = 0; i < 10; ++i)
my_printf("%s %s %u\n", "...", "and", i + 1);
my_printf("And here are my arguments :)\n");
for (int i = 0; i < argc; ++i)
my_printf("argv[%u] == %s\n", i, argv[i]);
}
Run Code Online (Sandbox Code Playgroud)
未定义行为和可能的堆栈损坏的问题是由其他原因引起的.在C++中,这很可能是由于通过C的变量参数列表传递非POD类型(即传递std::string给printf()可以做到这一点).
不幸的是,像"格式属性"这样的编译器扩展在这里没有用.但编译器可能会警告您非POD类型.例如,拨打电话my_printf(),std::string您将获得类似于此的警告:
./test.cc:7:46: error: cannot pass objects of non-trivially-copyable type ‘class std::basic_string<char>’ through ‘...’
std::printf(fmt, std::forward<T>(args)...);
^
Run Code Online (Sandbox Code Playgroud)
当然,可能还有其他事情会发生,编译器将无法为您捕获.不幸的是,没有比调试程序更好的方法,看看究竟是什么导致程序崩溃.
由于你正在进入C的黑暗水域和不安全的参数传递,调试器在这里是你的朋友,我也建议你使用Valgrind - 它非常有用这样的东西.
希望能帮助到你.祝好运!