我有一种特殊的格式,需要以空格分隔的标记和最后的空终止符(空是输出的一部分)。我创建了一个函数来将一系列以空格分隔的标记发送到输出流:
// C++ variadic template function to output tokens to a stream delimited by spaces
template <typename T>
void join(std::ostream& os, T const& arg)
{
// This is the last argument, so insert a null in the stream to delimit
os << arg << '\000';
}
// Join one, add a space, try again.
template <typename T, typename... Args>
void join(std::ostream& os, T const& arg, Args... args) // recursive variadic function
{
os << arg << " ";
join(os, args...);
}
这适用于 join(os, 1, foo, "THING", M_PI); 之类的事情。但是,我也有一些标记不需要以空格分隔,例如 join(os, "KEY=", val);。
我试着玩弄这些参数,想也许我可以在参数列表中填充一个 nullptr 并用它来重载方法,跳过空格,但我终究做不到了解如何进行这种重载。
在标准合规性更为普遍之前,我看到的关于可变参数模板的大多数问题都相当陈旧。如果在其他地方已经回答了这个问题,请指出我。我正在使用 GCC 7.3。
或者,告诉我我把应该非常简单的事情复杂化了。也许可变参数模板不是这个 bolt 的正确锤子?
最佳答案
介绍一个 helper
template <typename A, typename B>
struct pack_t {
const A& a;
const B& b;
};
template <typename A, typename B>
std::ostream& operator<<(std::ostream& os, pack_t<A, B> pac) {
return os << pac.a << pac.b;
}
template <typename A, typename B>
auto pack(const A& a, const B& b) noexcept {
return pack_t<A, B>{a, b};
}
像这样使用
join(std::cout, "Hello", "World", pack("pi=", 3.14));
完整代码(live)
#include <iostream>
template <typename A, typename B>
struct pack_t {
const A& a;
const B& b;
};
template <typename A, typename B>
std::ostream& operator<<(std::ostream& os, pack_t<A, B> pac) {
return os << pac.a << pac.b;
}
template <typename A, typename B>
auto pack(const A& a, const B& b) noexcept {
return pack_t<A, B>{a, b};
}
template <typename T>
void join(std::ostream& os, const T& arg) {
os << arg << '\0';
}
template <typename T, typename... Args>
void join(std::ostream& os, const T& arg, const Args&... args) {
os << arg << ' ';
join(os, args...);
}
int main() {
join(std::cout, "Hello", "World", pack("pi=", 3.14));
}
请注意,您可以通过聚合或继承将 pack_t 基于 std::tuple 来扩展助手以支持两个以上的参数。例如,
namespace impl {
template <typename T, std::size_t... Idx>
struct pack_t {
T v;
};
template <std::size_t... Idx, typename... Ts>
auto pack(std::index_sequence<Idx...>, Ts&&... vs) noexcept {
auto v = std::forward_as_tuple(std::forward<Ts>(vs)...);
return pack_t<decltype(v), Idx...>{std::move(v)};
}
template <typename T, std::size_t... Idx>
std::ostream& operator<<(std::ostream& os, pack_t<T, Idx...> args) {
return ((os << std::get<Idx>(std::move(args.v))), ...);
}
}
template <typename... Ts>
auto pack(Ts&&... vs) noexcept {
return impl::pack(
std::index_sequence_for<Ts...>{}, std::forward<Ts>(vs)...);
}
现在,您可以打包不同数量的参数 ( live )。
关于c++ - 可变递归模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49786142/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我正在使用Mandrill的RubyAPIGem并使用以下简单的测试模板:testastic按照Heroku指南中的示例,我有以下Ruby代码:require'mandrill'm=Mandrill::API.newrendered=m.templates.render'test-template',[{:header=>'someheadertext',:main_section=>'Themaincontentblock',:footer=>'asdf'}]mail(:to=>"JaysonLane",:subject=>"TestEmail")do|format|format.h
所以这可能有点令人困惑,但请耐心等待。简而言之,我想遍历具有特定键值的所有属性,然后如果值不为空,则将它们插入到模板中。这是我的代码:属性:#===DefaultfileConfigurations#default['elasticsearch']['default']['ES_USER']=''default['elasticsearch']['default']['ES_GROUP']=''default['elasticsearch']['default']['ES_HEAP_SIZE']=''default['elasticsearch']['default']['MAX_OP
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
我有一个随机大小的散列,它可能有类似"100"的值,我想将其转换为整数。我知道我可以使用value.to_iifvalue.to_i.to_s==value来做到这一点,但我不确定我将如何在我的散列中递归地做到这一点,考虑到一个值可以是一个字符串,或一个数组(哈希或字符串),或另一个哈希。 最佳答案 这是一个非常简单的递归实现(尽管必须同时处理数组和散列会增加一些技巧)。deffixnumifyobjifobj.respond_to?:to_i#IfwecancastittoaFixnum,doit.obj.to_ielsifobj
我经常迷上ruby的一件事是递归模式。例如,假设我有一个数组,它可能包含无限深度的数组作为元素。所以,例如:my_array=[1,[2,3,[4,5,[6,7]]]]我想创建一个方法,可以将数组展平为[1,2,3,4,5,6,7]。我知道.flatten可以完成这项工作,但这个问题是作为我经常遇到的递归问题的一个例子-因此我试图找到一个更可重用的解决方案。简而言之-我猜这种事情有一个标准模式,但我想不出任何特别优雅的东西。任何想法表示赞赏 最佳答案 递归是一种方法,它不依赖于语言。您在编写算法时要考虑两种情况:再次调用函数的情
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=