Questions tagged «template-meta-programming»

模板元编程是一种元编程技术,其中编译器使用模板来生成临时源代码,该临时源代码由编译器与其余源代码合并,然后进行编译。

26
模板检查是否存在类成员函数?
是否可以编写一个模板来更改行为,具体取决于是否在类上定义了某个成员函数? 这是我要写的一个简单示例: template<class T> std::string optionalToString(T* obj) { if (FUNCTION_EXISTS(T->toString)) return obj->toString(); else return "toString not defined"; } 因此,如果class T已经toString()定义,则使用它;否则,事实并非如此。我不知道该怎么做的神奇部分是“ FUNCTION_EXISTS”部分。

20
您如何遍历std :: tuple的元素?
我如何遍历一个元组(使用C ++ 11)?我尝试了以下方法: for(int i=0; i<std::tuple_size<T...>::value; ++i) std::get<i>(my_tuple).do_sth(); 但这不起作用: 错误1:抱歉,未实现:无法将“侦听器...”扩展为固定长度的参数列表。 错误2:我无法出现在常量表达式中。 那么,如何正确遍历元组的元素?


1
更疯狂的精神-解析器类型(规则vs int_parser <>)和元编程技术
问题在底部以粗体显示,该问题在结尾处也用蒸馏代码片段加以概括。 我正在尝试将我的类型系统(类型系统从类型到字符串,从类型到字符串)统一为一个组件(由Lakos定义)。我正在使用boost::array,boost::variant和boost::mpl,以实现此目的。我想将我的类型的解析器和生成器规则统一在一个变量中。有一个未定义的类型,一个int4(见下文)类型和一个int8类型。变体读取为variant&lt;undefined, int4,int8&gt;。 int4特性: struct rbl_int4_parser_rule_definition { typedef boost::spirit::qi::rule&lt;std::string::iterator, rbl_int4()&gt; rule_type; boost::spirit::qi::int_parser&lt;rbl_int4&gt; parser_int32_t; rule_type rule; rbl_int4_parser_rule_definition() { rule.name("rbl int4 rule"); rule = parser_int32_t; } }; template&lt;&gt; struct rbl_type_parser_rule&lt;rbl_int4&gt; { typedef rbl_int4_parser_rule_definition string_parser; }; 上面的变体以未定义开始,然后初始化规则。我遇到了一个问题,该问题导致了50页的错误,我终于设法找到了它,operator=在分配期间使用了Variant ,并且boost::spirit::qi::int_parser&lt;&gt;不能将a分配给另一个(operator =)。 相比之下,我的未定义类型没有问题: struct rbl_undefined_parser_rule_definition { typedef boost::spirit::qi::rule&lt;std::string::iterator, void()&gt; rule_type; rule_type rule; rbl_undefined_parser_rule_definition() { rule.name("undefined parse …

5
如何对可变参数模板函数的异构参数包进行通用计算?
前提: 在使用了可变参数模板后,我意识到,要完成琐碎的元编程任务之外的任何事情,很快就会变得很麻烦。特别是,我发现自己希望的执行方式上的参数包一般操作如迭代,拆分,循环在一个std::for_each样的方式,等等。 在观看了C ++和Beyond 2012的Andrei Alexandrescu的关于static ifC ++(从D编程语言中借用的结构)的可取性的演讲之后,我感到有些东西static for也将派上用场-我感到更多这样的static结构可以带来利益。 于是我开始想知道如果有一种方法来实现这样的一个可变参数模板函数的参数包(伪代码): template&lt;typename... Ts&gt; void my_function(Ts&amp;&amp;... args) { static for (int i = 0; i &lt; sizeof...(args); i++) // PSEUDO-CODE! { foo(nth_value_of&lt;i&gt;(args)); } } 它将在编译时转换为如下形式: template&lt;typename... Ts&gt; void my_function(Ts&amp;&amp;... args) { foo(nth_value_of&lt;0&gt;(args)); foo(nth_value_of&lt;1&gt;(args)); // ... foo(nth_value_of&lt;sizeof...(args) - 1&gt;(args)); } 原则上,static_for将允许进行更精细的处理: template&lt;typename... Ts&gt; …

1
void_t“可以实现概念”吗?
我正在观看Walter Brown在CppCon2014上有关模板元编程的第二部分,在此期间他讨论了他的新颖void_t&lt;&gt;结构的用法。彼得·索默拉德(Peter Sommerlad)在演讲中问了我一个不太明白的问题。(链接直接指向问题,正在讨论的代码是在此之前直接进行的) 索默拉德问 沃尔特,这是否意味着我们实际上可以立即实施精简概念? 沃尔特回应 哦耶!我已经完成了...它没有完全相同的语法。 我了解这次交流是关于Concepts Lite。这种模式真的那么通用吗?无论出于什么原因,我都没有看到它。有人可以解释(或素描)这样的样子吗?这仅仅是关于enable_if和定义特征,还是提问者指的是什么? 该void_t模板定义如下: template&lt;class ...&gt; using void_t = void; 然后,他使用它来检测类型语句是否格式正确,并使用它来实现is_copy_assignable类型特征: //helper type template&lt;class T&gt; using copy_assignment_t = decltype(declval&lt;T&amp;&gt;() = declval&lt;T const&amp;&gt;()); //base case template template&lt;class T, class=void&gt; struct is_copy_assignable : std::false_type {}; //SFINAE version only for types where copy_assignment_t&lt;T&gt; is well-formed. template&lt;class T&gt; …

3
如何在编译时获取多维std :: vector的深度?
我有一个函数,需要一个多维参数std::vector,需要将深度(或维数)作为模板参数传递。与其对这个值​​进行硬编码,我想编写一个constexpr函数,该函数将std::vector并将深度作为unsigned integer值返回。 例如: std::vector&lt;std::vector&lt;std::vector&lt;int&gt;&gt;&gt; v = { { { 0, 1}, { 2, 3 } }, { { 4, 5}, { 6, 7 } }, }; // Returns 3 size_t depth = GetDepth(v); 不过,这需要在编译时完成,因为此深度将作为模板参数传递给模板函数: // Same as calling foo&lt;3&gt;(v); foo&lt;GetDepth(v)&gt;(v); 有什么办法吗?

4
模板元编程
有人可以向我解释一下,为什么第一个模板元编程方式将进入无限循环,而第二个模板正确运行。 #include &lt;iostream&gt; using namespace std; template&lt;int N, int M&gt; struct commondivs { static const int val = (N&lt;M) ? commondivs&lt;N,(M-N)&gt;::val : commondivs&lt;(N-M),M&gt;::val; }; template&lt;int N&gt; struct commondivs&lt;N,N&gt; { static const int val = N; }; int commondiv(int N, int M){ if(N==M){ return N; } return (N&lt;M)?commondiv(N,(M-N)):commondiv((N-M),M); } int main() …

2
将概念传递给功能
由于将概念定义为编译时谓词,是否还可以将这些谓词实际重用于编译时算法?例如,可以检查元组中的所有类型是否都符合概念?据我所知,不可能以任何方式将概念传递给函数,这使我重新回到在这些情况下使用模板。 #include &lt;type_traits&gt; template&lt;typename T&gt; concept FloatLike = std::is_same_v&lt;T, float&gt;; struct IsFloat { template&lt;typename U&gt; constexpr static bool test() { return FloatLike&lt;U&gt;; } }; template&lt;typename Predicate, typename... T&gt; constexpr bool all_types() { return (Predicate::template test&lt;T&gt;() &amp;&amp; ...); } int main() { static_assert(all_types&lt;IsFloat, float, float&gt;()); static_assert(!all_types&lt;IsFloat, float, int&gt;()); } 我想做的就是这样,所以我不必一直包装这个概念就可以使用它: template&lt;concept …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.