Tag: 模板元编程

为什么标准中不允许初始化模板参数列表中的常量相关types?

在对这篇文章的回答“ (部分地)专门化非依赖types的非types模板参数 ”中,它指出: 对应于专门的非types参数的模板参数的types不应该依赖于专门化的参数。 [例如: template <class T, T t> struct C {}; template <class T> struct C<T, 1>; // error template< int X, int (*array_ptr)[X] > class A {}; int array[5]; template< int X > class A<X,&array> { }; // error – 例子] 我的问题是为什么这个限制在这里? 至less有一个用例,我发现这个限制干扰了编写干净的代码。 例如 template <typename T, T*> struct test; template <typename […]

检查是否存在C ++成员函数,可能受保护

我试图检测一个类是否有一个特定的函数(具体来说是std::enable_shared_from_this<Some Unknown Class> shared_from_this() ,它是从std::enable_shared_from_this<Some Unknown Class>inheritance的)。 为了使事情更加复杂,我需要知道它是否具有这个function,即使它是从远处的基类inheritance的,或者是使用受保护的访问inheritance的。 我已经看过其他问题,比如这个 ,但是提供的方法不适用于检测受保护的成员函数。 目前我正在使用的方法如下: template <class T> struct shared_from_this_wrapper : public T { template <class U> static auto check( U const & t ) -> decltype( t.shared_from_this(), std::true_type() ); static auto check( … ) -> decltype( std::false_type() ); }; template<class T> struct has_shared_from_this : decltype(shared_from_this_wrapper<T>::check(std::declval<shared_from_this_wrapper<T>>())) { }; 我目前的解决scheme的缺陷是,它不适用于final宣布的类。 […]

编译时常量id

鉴于以下情况: template<typename T> class A { public: static const unsigned int ID = ?; }; 我希望ID为每个T生成一个唯一的编译时间ID。我已经考虑过了__COUNTER__和boost PP库,但到目前为止还没有成功。 我怎样才能做到这一点? 编辑:ID必须可以在switch语句中使用 编辑2:所有基于静态方法或成员的地址的答案是不正确的。 尽pipe它们确实创build了一个唯一的ID,但它们在编译时不能parsing,因此不能用作switch语句的例子。

为什么C ++模板使用尖括号语法?

标题问题是指在1990年左右引入模板的C ++标准中的devise决策。 为什么devise师使用<> (尖括号)而不是() ( () (圆括号)? 这样做会节省大量程序员的位移有关的错误 std::vector<std::vector<int>> // does not work until C++11 这只在C ++ 11中得到了修复。 我没有看到引入额外语法的理由,可以说,圆括号可以达到同样的目的,同时保持更改极简。 绝对可以使用 template(typename T) // Define template if round brackets could be used mytemplate { … } … … mytemplate(mytemplate(int)) obj; //Instantiate template when round brackets could be used 熟悉C ++历史的人能否挖掘使用尖括号的原始devise原理? 或者,你可以说明为什么其他解决scheme不会有效?

自动select一个足够容纳指定数字的variablestypes

有没有什么办法在C ++中定义一个足够大的types来保存至多一个特定的数字,大概是使用一些聪明的模板代码。 例如,我想能够写: – Integer<10000>::type dataItem; 并有这种typesparsing为最小的types足够大,以保持指定的值? 背景:我需要使用来自外部数据文件的脚本来生成一些variables定义。 我想我可以让脚本看看值,然后根据值使用uint8_t , uint16_t , uint32_t等等,但是看起来更优雅的是将大小构build到生成的C ++代码中。 我看不出有什么办法可以做到这一点,但知道C ++模板,我敢肯定有一种方法。 有任何想法吗?

void_t“可以实现概念”?

我正在观看Walter Brown的CppCon2014谈话模板元编程的第二部分,在此期间他讨论了他的小说void_t<>构造的void_t<> 。 在他的演讲中,彼得·索莫拉德问他一个我不太明白的问题。 (链接直接回答问题,正在讨论的代码直接发生在那之前) Sommerlad问道 沃尔特,这是否意味着我们现在可以实现概念lite? 沃尔特回应 哦耶! 我已经完成了…它没有完全相同的语法。 我理解这个交stream是关于概念精简版。 这种模式真的是多才多艺的? 不pipe出于什么原因,我都没有看到它。 有人可以解释(或草图)这样的事情吗? 这仅仅是关于enable_if和定义特征,或者提问者提到的是什么? void_t模板定义如下: template<class …> using void_t = void; 然后他使用它来检测types语句是否格式正确,使用它来实现is_copy_assignabletypes特征: //helper type template<class T> using copy_assignment_t = decltype(declval<T&>() = declval<T const&>()); //base case template template<class T, class=void> struct is_copy_assignable : std::false_type {}; //SFINAE version only for types where copy_assignment_t<T> is well-formed. template<class […]

更多精神疯狂 – parsing器types(规则vs int_parser <>)和元编程技术

问题是在底部粗体,问题也是由蒸馏代码片段总结的。 我试图统一我的types系统(types系统做和从types到string)到一个单一的组件(由Lakos定义)。 我正在使用boost::array , boost::variant和boost::mpl ,以实现此目的。 我希望我的types的parsing器和生成器规则统一在一个变体中。 有一个未定义的types,一个int4(见下文)types和一个int8types。 该变体读作variant<undefined, int4,int8> 。 int4特征: struct rbl_int4_parser_rule_definition { typedef boost::spirit::qi::rule<std::string::iterator, rbl_int4()> rule_type; boost::spirit::qi::int_parser<rbl_int4> parser_int32_t; rule_type rule; rbl_int4_parser_rule_definition() { rule.name("rbl int4 rule"); rule = parser_int32_t; } }; template<> struct rbl_type_parser_rule<rbl_int4> { typedef rbl_int4_parser_rule_definition string_parser; }; 上面的变种开始为未定义,然后我初始化规则。 我有一个问题,这导致了50页的错误,我终于设法追查下来,Variant在赋值时使用operator= ,而boost::spirit::qi::int_parser<>不能赋给另一个(operator = )。 相比之下,我的undefinedtypes没有问题: struct rbl_undefined_parser_rule_definition { typedef boost::spirit::qi::rule<std::string::iterator, void()> rule_type; rule_type […]

TMP:如何推广vector的笛卡尔乘积?

有一个优秀的C ++解决scheme(实际上是2个解决scheme:recursion和非recursion)到整数向量向量的笛卡尔乘积 。 为了说明/简单起见,让我们只关注非recursion版本 。 我的问题是,如何可以推广这个代码与模板采取一个std::tuple同构向量std::tuple看起来像这样: {{2,5,9},{"foo","bar"}} 并生成一个tuple向量 {{2,"foo"},{2,"bar"},{5,"foo"},{5,"bar"},{9,"foo"},{9,"bar"}} 如果它使生活更容易,让我们假设input中的内部向量是均匀的。 所以这样的input是不允许的 : {{5,"baz"}{'c',-2}} 编辑改变input从锯齿状vector到元组

在编译时build立和访问types列表

我想要实现以下使用C ++模板元编程。 我希望build立一个types列表,然后把这些types一起收集起来,并在列表中进一步编译处理。 举个例子: foo.h中: class Foo { … }; // INSERT ANY CODE HERE bar.h: class Bar { … }; // INSERT ANY CODE HERE main.h: #include "foo.h" #include "bar.h" struct list_of_types { typedef /* INSERT ANY CODE HERE */ type; }; 我可以插入任何代码到上面的插槽中,只要list_of_types :: typeparsing为包含typesFoo和Bar的列表的某种表示(例如boost :: mpl :: vector)。 以下限制适用: foo.h中的代码不应该知道bar.h中的代码,反之亦然。 应该可以改变main.h中的#include指令的顺序,而不是更改任何其他代码。 在main.h中的代码不应该改变,如果我进一步包含进一步的头添加到列表中的types。 types列表必须在编译时可用。 […]

我怎样才能检查一个types是一个给定的类模板的实例?

是否有可能检查一个types是一个特定模板的实例? 我有一个类模板,其中一个模板参数必须是特定模板的实例或其他types。 例如,考虑一个types列表的简单定义: struct null_type; template <typename Head, typename Tail> struct typelist { // Tail must be a typelist or null_type typedef Head head; typedef Tail tail; }; 现在,我想确保为Tail模板参数提供的types始终是typelist或null_type的实例。 我可以使用部分特化来为这些情况定义模板,如下所示: template <typename Head, typename Tail> struct typelist; // default, not defined template <typename Head, typename H, typename T> struct typelist< Head, typelist<H,T> > // Tail […]