这个问题之所以存在是因为它具有历史意义,但它不被认为是本网站的一个好的,主题上的问题,所以请不要将它作为证据,你可以在这里提出类似的问题.
您在C++中看到的最酷的元编程实例是什么?
您在C++中看到的元编程有哪些实际用途?
可能重复:
从迭代器获取const_iterator
我想写一元函数返回相应的const_iterator从iterator
template <class Iterator>
struct get_const_iterator
{
typedef ??? type;
};
Run Code Online (Sandbox Code Playgroud)
get_const_iterator<int*>::type 一定是 const int*get_const_iterator<const int*>::type 一定是 const int* get_const_iterator<int* const>::type必须是const int*或const int* const,我不在乎get_const_iterator<std::list<char>::iterator>::type 一定是 std::list<char>::const_iterator等等
可以使用iterator_traits或不使用它们吗?
编辑:我们假设如果2个容器具有相同的iterator类型,那么它们也具有相同的const_iterator类型.我认为这是一个合理的假设,虽然理论上并不完全正确.
是否可以检查类型是否是特定模板的实例化?
我有一个类模板,其中一个模板参数必须是特定模板的实例化,或其他类型.例如,考虑一个类型列表的简单定义:
struct null_type;
template <typename Head, typename Tail>
struct typelist
{
// Tail must be a typelist or null_type
typedef Head head;
typedef Tail tail;
};
Run Code Online (Sandbox Code Playgroud)
现在,我想,以确保规定的类型Tail模板参数始终为的一个实例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 = typelist, ok
{
typedef Head head;
typedef typelist<H,T> tail;
};
template <typename Head>
struct typelist< Head, null_type > // Tail …Run Code Online (Sandbox Code Playgroud) 我只是注意到Scala有宏,但我从未见过任何使用它们的代码.它们似乎与C预处理器宏等完全不同.通过阅读宏的概述,看起来它们看起来不像以前在Scala中提供的任何东西.在动机标题下,有一个宏启用的事项列表:
- 语言虚拟化(原始编程语言的重载/覆盖语义,以实现DSL的深度嵌入),
- 程序具体化(为程序提供检查自己代码的方法),
- 自我优化(基于程序实现的特定于域的优化的自我应用),
- 算法程序构造(使用编程语言支持的抽象编写繁琐的代码).
稍后在菜单中,有实验宏功能,例如类型宏,quasiquotes,无类型宏等等.显然需要这个!
对于那些构建非常复杂的库并且对Scala有深刻理解的人来说,所有这些看起来都很不错.但是宏也为普通的Scala开发人员提供了一些东西吗?使用宏会使我的Scala代码变得更好吗?
这是另一个问题的后续行动.它指的是同样的问题(我希望),但使用一个完全不同的例子来说明它.原因是在前面的示例中,只有实验性GCC 4.9因编译器错误而失败.在此示例中,Clang和GCC 4.8.1也以不同方式失败:Clang产生意外结果,GCC 4.8.1报告不同的错误消息.
上一个问题的答案或多或少地说代码是有效的,问题在于GCC的实验版本.但这个结果让我更加怀疑.几个月来我一直困扰着我怀疑有相关(或相同)的问题,这是我第一次有一个小的具体例子来说明.
所以,这里有一些代码.首先,一些通用代码将SFINAE应用于由可变参数模板别名元函数指定的任意测试F:
#include <iostream>
using namespace std;
using _true = integral_constant <bool, true>;
using _false = integral_constant <bool, false>;
template <typename T> using pass = _true;
template <template <typename...> class F>
struct test
{
template <typename... A> static _false _(...);
template <typename... A> static pass <F <A...> > _(int);
};
template <template <typename...> class F, typename... A>
using sfinae = decltype(test <F>::template _<A...>(0));
Run Code Online (Sandbox Code Playgroud)
第二,一个特定的测试,检查给定的类是否定义了一个名为的类型type:
template <typename T> using type_of = …Run Code Online (Sandbox Code Playgroud) c++ templates template-meta-programming variadic-templates template-aliases
我想constexpr if在编译时使用分支,但最新的MSVC编译器似乎不支持它.有以下替代方案吗?:
template<typename T>
void MyFunc()
{
if constexpr(MeetsConditions<T>::value)
{
FunctionA<T>();
}
else
{
FunctionB<T>();
}
}
Run Code Online (Sandbox Code Playgroud)
简而言之:我可以模拟constexpr if编译器不支持的时间吗?
我正在尝试使用unordered_map.但在某些服务器中我们没有tr1库.在那些情况下,我想使用地图.所以,我想写一个头文件,我将使用以下行之一.
typedef tr1::unordered_map hashmap;
typedef map hashmap;
Run Code Online (Sandbox Code Playgroud)
我的问题是我在这里使用不同类型的地图.
map<string, string>
map<string, int>
map <string, map<string,int>> ..etc
Run Code Online (Sandbox Code Playgroud)
如果我可以使用的typedef别名地图或unordered_map为HashMap,那么我可以使用地图的hashmap<string, string>,hashmap<int, int>在代码中.
有没有办法做到这一点或如果有更好的方法请建议我.
谢谢Vinod
我有一个函数at旨在通过运行时指定的索引访问std :: tuple元素
template<std::size_t _Index = 0, typename _Tuple, typename _Function>
inline typename std::enable_if<_Index == std::tuple_size<_Tuple>::value, void>::type
for_each(_Tuple &, _Function)
{}
template<std::size_t _Index = 0, typename _Tuple, typename _Function>
inline typename std::enable_if < _Index < std::tuple_size<_Tuple>::value, void>::type
for_each(_Tuple &t, _Function f)
{
f(std::get<_Index>(t));
for_each<_Index + 1, _Tuple, _Function>(t, f);
}
namespace detail { namespace at {
template < typename _Function >
struct helper
{
inline helper(size_t index_, _Function f_) : index(index_), f(f_), count(0) {}
template < typename _Arg …Run Code Online (Sandbox Code Playgroud) 我的一个项目中有很多自定义数据类型,它们共享一个公共基类.
我的数据(来自数据库)有一个数据类型,它由基类的枚举区分.我的体系结构允许特定的数据类型专门用于派生类,或者它可以由基类处理.
当我构造一个我特定的数据类型时,我通常直接调用构造函数:
Special_Type_X a = Special_Type_X("34.34:fdfh-78");
a.getFoo();
Run Code Online (Sandbox Code Playgroud)
有一些模板魔术也可以像这样构建它:
Type_Helper<Base_Type::special_type_x>::Type a = Base_Type::construct<Base_Type::special_type_x>("34.34:fdfh-78");
a.getFoo();
Run Code Online (Sandbox Code Playgroud)
对于枚举类型的某些值,可能没有专门化
Type_Helper<Base_Type::non_specialized_type_1>::Type == Base_Type
Run Code Online (Sandbox Code Playgroud)
当我从数据库中获取数据时,在编译时不知道数据类型,因此有第三种方法来构造数据类型(来自QVariant):
Base_Type a = Base_Type::construct(Base_type::whatever,"12.23@34io{3,3}");
Run Code Online (Sandbox Code Playgroud)
但是我当然希望调用正确的构造函数,所以该方法的实现过去看起来像:
switch(t) {
case Base_Type::special_type_x:
return Base_Type::construct<Base_Type::special_type_x>(var);
case Base_Type::non_specialized_type_1:
return Base_Type::construct<Base_Type::non_specialized_type_1>(var);
case Base_Type::whatever:
return Base_Type::construct<Base_Type::whatever>(var);
//.....
}
Run Code Online (Sandbox Code Playgroud)
这段代码是重复的,因为基类也可以处理新类型(添加到枚举),我提出了以下解决方案:
// Helper Template Method
template <Base_Type::type_enum bt_itr>
Base_Type construct_switch(const Base_Type::type_enum& bt, const QVariant& v)
{
if(bt_itr==bt)
return Base_Type::construct<bt_itr>(v);
return construct_switch<(Base_Type::type_enum)(bt_itr+1)>(bt,v);
}
// Specialization for the last available (dummy type): num_types
template <>
Base_Type construct_switch<Base_Type::num_types>(const Base_Type::type_enum& bt, const QVariant&)
{ …Run Code Online (Sandbox Code Playgroud) 假设我收到一个模板T1和T2的两个参数.如果我知道T1本身就是一个模板化的类(例如,一个容器),并且T2可以是任何东西,我是否可以确定T1的基本模板类型并使用T2作为其参数重建它?
例如,如果我收到std::vector<int>并且std::string,我想自动建立std::vector<std::string>.但是如果给我std::set<bool>和double,它会产生std::set<double>.
在查看了type_traits,相关博客和其他问题之后,我没有看到解决此问题的一般方法.我目前可以看到完成此任务的唯一方法是为每个可以作为T1传入的类型构建模板适配器.
例如,如果我有:
template<typename T_inner, typename T_new>
std::list<T_new> AdaptTemplate(std::list<T_inner>, T_new);
template<typename T_inner, typename T_new>
std::set<T_new> AdaptTemplate(std::set<T_inner>, T_new);
template<typename T_inner, typename T_new>
std::vector<T_new> AdaptTemplate(std::vector<T_inner>, T_new);
Run Code Online (Sandbox Code Playgroud)
我应该能够使用decltype并依赖运算符重载来解决我的问题.有点像:
template <typename T1, typename T2>
void MyTemplatedFunction() {
using my_type = decltype(AdaptTemplate(T1(),T2()));
}
Run Code Online (Sandbox Code Playgroud)
我错过了什么吗?有更好的方法吗?
我为什么要这样做?
我正在构建一个C++库,我希望简化用户构建模块化模板所需的操作.例如,如果用户想要构建基于代理的模拟,他们可能会配置具有生物类型的世界模板,人口管理器,环境管理器和系统管理器.
每个管理人员还需要知道有机体类型,因此声明可能类似于:
World< NeuralNetworkAgent, EAPop<NeuralNetworkAgent>,
MazeEnvironment<NeuralNetworkAgent>,
LineageTracker<NeuralNetworkAgent> > world;
Run Code Online (Sandbox Code Playgroud)
我宁愿用户不必NeuralNetworkAgent每次都重复.如果我能够更改模板参数,则可以使用默认参数,并且可以将上述内容简化为:
World< NeuralNetworkAgent, EAPop<>, MazeEnvironment<>, LineageTracker<> > world;
Run Code Online (Sandbox Code Playgroud)
此外,从一种世界类型转换为另一种世界类型更容易,而不必担心类型错误.
当然,我可以使用static_assert处理大多数错误,只处理较长的声明,但我想知道是否有更好的解决方案.