标签: template-meta-programming

是否可以编写模板来检查函数的存在?

是否可以编写一个模板来改变行为,具体取决于是否在类上定义了某个成员函数?

这是我想写的一个简单例子:

template<class T>
std::string optionalToString(T* obj)
{
    if (FUNCTION_EXISTS(T->toString))
        return obj->toString();
    else
        return "toString not defined";
}
Run Code Online (Sandbox Code Playgroud)

所以,如果class T已经toString()确定的话,就使用它; 否则,它没有.我不知道怎么做的神奇部分是"FUNCTION_EXISTS"部分.

c++ templates sfinae template-meta-programming

458
推荐指数
20
解决办法
14万
查看次数

C++模板Turing-complete?

我被告知C++中的模板系统在编译时是图灵完备的.这篇文章以及维基百科都提到了这一点.

你能提供一个利用这个属性的计算的重要例子吗?

这个事实在实践中有用吗?

c++ templates turing-complete template-meta-programming

100
推荐指数
9
解决办法
3万
查看次数

你如何迭代std :: tuple的元素?

如何迭代元组(使用C++ 11)?我尝试了以下方法:

for(int i=0; i<std::tuple_size<T...>::value; ++i) 
  std::get<i>(my_tuple).do_sth();
Run Code Online (Sandbox Code Playgroud)

但这不起作用:

错误1:抱歉,未实现:无法将"Listener ..."扩展为固定长度的参数列表.
错误2:我不能出现在常量表达式中.

那么,我如何正确迭代元组的元素?

c++ iteration template-meta-programming c++11 stdtuple

92
推荐指数
12
解决办法
6万
查看次数

更多精神疯狂 - 解析器类型(规则与int_parser <>)和元编程技术

问题在底部以粗体显示,问题也通过最终的蒸馏代码片段进行了总结.

我试图统一我的类型系统(类型系统从类型到字符串)和单个组件(由Lakos定义).我正在使用boost::array,, boost::variantboost::mpl,以实现这一目标.我想让我的类型的解析器和生成器规则统一在一个变体中.有一个未定义的类型,一个int4(见下文)类型和一个int8类型.该变体读作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;
};
Run Code Online (Sandbox Code Playgroud)

上面的变体从未定义开始,然后我初始化规则.我有一个问题,导致50页的错误,我终于设法跟踪它,Variant operator=在分配期间使用,而a boost::spirit::qi::int_parser<>不能分配给另一个(operator =).

相比之下,我的未定义类型没有问题:

struct rbl_undefined_parser_rule_definition
{
  typedef boost::spirit::qi::rule<std::string::iterator, void()> rule_type;
  rule_type rule;

  rbl_undefined_parser_rule_definition()
  {
    rule.name("undefined parse rule");
    rule = boost::spirit::qi::eps;
  }
};

template<>
struct rbl_type_parser_rule<rbl_undefined>
{
  typedef rbl_undefined_parser_rule_definition string_parser;
};
Run Code Online (Sandbox Code Playgroud)

蒸馏问题:

#include <string>
#include <boost/spirit/include/qi.hpp> …
Run Code Online (Sandbox Code Playgroud)

c++ boost boost-spirit template-meta-programming

80
推荐指数
1
解决办法
3854
查看次数

如何在可变参数模板函数的异构参数包上进行泛型计算?

前提:

在稍微使用了可变参数模板之后,我意识到实现稍微超出简单的元编程任务的任何东西很快变得非常麻烦.特别是,我发现自己希望的执行方式上的参数包一般操作迭代,拆分,循环在一个std::for_each样的方式,等等.

在观看了由安德烈Alexandrescu的本次讲座由C++和超越2012年的愿望static if成C++(从借来构建d编程语言),我的感觉是某种static for会来得心应手,以及-我觉得更多的这些的static结构能带来好处.

所以我开始想知道是否有办法为变量模板函数(伪代码)的参数包实现类似的东西:

template<typename... Ts>
void my_function(Ts&&... args)
{
    static for (int i = 0; i < sizeof...(args); i++) // PSEUDO-CODE!
    {
        foo(nth_value_of<i>(args));
    }
}
Run Code Online (Sandbox Code Playgroud)

哪个会在编译时被翻译成这样的东西:

template<typename... Ts>
void my_function(Ts&&... args)
{
    foo(nth_value_of<0>(args));
    foo(nth_value_of<1>(args));
    // ...
    foo(nth_value_of<sizeof...(args) - 1>(args));
}
Run Code Online (Sandbox Code Playgroud)

原则上,static_for将允许更精细的处理:

template<typename... Ts>
void foo(Ts&&... args)
{
    constexpr s …
Run Code Online (Sandbox Code Playgroud)

c++ iteration template-meta-programming variadic-templates c++11

77
推荐指数
3
解决办法
6371
查看次数

void_t"可以实现概念"吗?

我正在观看Walter Brown的CppCon2014关于模板元编程的第二部分,在此期间他讨论了他的新颖void_t<>结构的用法.在他的演讲中,Peter Sommerlad问他一个我不太明白的问题.(链接直接转到问题,正在讨论的代码直接发生在那之前)

索默拉德问道

沃尔特,这是否意味着我们现在实际上可以实现概念精简版?

沃尔特回应了什么

哦耶!我已经完成了......它没有完全相同的语法.

我理解这个交换是关于Concepts Lite的.这种模式真的那么多才多艺吗?无论出于何种原因,我都没有看到它.有人可以解释(或描绘)这样的事情会是什么样子?这是关于enable_if和定义特征,还是提问者指的是什么?

void_t模板定义如下:

template<class ...> using void_t = void;
Run Code Online (Sandbox Code Playgroud)

然后他使用它来检测类型语句是否格式正确,使用它来实现is_copy_assignable类型特征:

//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 T>
struct is_copy_assignable<T, void_t<copy_assignment_t<T>>> 
: std::is_same<copy_assignment_t<T>,T&> {};
Run Code Online (Sandbox Code Playgroud)

由于这个话题,我理解这个例子是如何工作的,但是我没有看到我们如何从这里得到像Concepts Lite这样的东西.

c++ templates template-meta-programming c++11 c++-concepts

68
推荐指数
1
解决办法
7055
查看次数

特质和政策有什么区别?

我有一个类,我试图配置它的行为.

template<int ModeT, bool IsAsync, bool IsReentrant> ServerTraits;
Run Code Online (Sandbox Code Playgroud)

然后我有我的服务器对象本身:

template<typename TraitsT>
class Server {...};
Run Code Online (Sandbox Code Playgroud)

我的问题是我上面的用法是我的命名错误吗?我的模板化参数实际上是一个策略而不是特征吗?

什么是模板化论证的特征与政策相比?

c++ type-traits policy-based-design template-meta-programming

59
推荐指数
2
解决办法
2万
查看次数

自动选择足够大的变量类型以保存指定的数字

在C++中是否有任何方法可以定义一个足以容纳最多特定数字的类型,大概是使用一些聪明的模板代码.例如,我希望能够写: -

Integer<10000>::type dataItem;
Run Code Online (Sandbox Code Playgroud)

并将该类型解析为足以保持指定值的最小类型?

背景:我需要使用外部数据文件中的脚本生成一些变量定义.我想我可以使脚本看看值,然后使用uint8_t,uint16_t,uint32_t等,这取决于价值,但它似乎更优雅建设规模到生成的C++代码.

我看不出任何方法可以制作一个可以做到这一点的模板,但是知道C++模板,我确信有办法.有任何想法吗?

c++ templates template-meta-programming

54
推荐指数
6
解决办法
4535
查看次数

如何在编译时获得多维 std::vector 的深度?

我有一个采用多维的函数,std::vector并需要将深度(或维数)作为模板参数传入。我不想对这个值进行硬编码,我想编写一个constexpr函数,它将std::vector深度作为unsigned integer值返回。

例如:

std::vector<std::vector<std::vector<int>>> v =
{
    { { 0, 1}, { 2, 3 } },
    { { 4, 5}, { 6, 7 } },
};

// Returns 3
size_t depth = GetDepth(v);
Run Code Online (Sandbox Code Playgroud)

这需要在编译时完成,因为这个深度将作为模板参数传递给模板函数:

// Same as calling foo<3>(v);
foo<GetDepth(v)>(v);
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?

c++ templates stdvector template-meta-programming constexpr

45
推荐指数
2
解决办法
1745
查看次数

编译时常量id

鉴于以下内容:

template<typename T>
class A
{
public:
    static const unsigned int ID = ?;
};
Run Code Online (Sandbox Code Playgroud)

我希望ID为每个T生成一个唯一的编译时间ID.我考虑过__COUNTER__并且增强PP库但到目前为止都没有成功.我怎样才能做到这一点?

编辑:ID必须可用作switch语句中的大小写

Edit2:基于静态方法或成员地址的所有答案都不正确.尽管它们确实创建了唯一的ID,但它们在编译时未得到解析,因此不能用作switch语句的情况.

c++ templates template-meta-programming

43
推荐指数
4
解决办法
8410
查看次数