我想在模板类中定义一些模板成员方法,如下所示:
template <typename T>
class CallSometing {
public:
void call (T tObj); // 1st
template <typename A>
void call (T tObj, A aObj); // 2nd
template <typename A>
template <typename B>
void call (T tObj, A aObj, B bObj); // 3rd
};
template <typename T> void
CallSometing<T>::call (T tObj) {
std::cout << tObj << ", " << std::endl;
}
template <typename T>
template <typename A> void
CallSometing<T>::call (T tObj, A aObj) {
std::cout << tObj << ", " << aObj …Run Code Online (Sandbox Code Playgroud) c++ templates arguments compiler-errors template-meta-programming
我最近写了一个STL Vector的实现作为编程练习.该程序编译但我收到一个奇怪的错误说:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Run Code Online (Sandbox Code Playgroud)
我以前从来没有想过这个错误,也不确定在我的实现中究竟应该改变什么才能使它正常运行.
有人可以查看我的代码,看看在这个特定情况下是否有任何东西突然出现错误?对不起,我不能更具体,我不知道在哪里看自己,提前谢谢.
#include <iostream>
#include <string>
#include <cassert>
#include <algorithm>
using namespace std;
template <class T>
class Vector
{
public:
typedef T * iterator;
Vector();
Vector(unsigned int size);
Vector(unsigned int size, const T & initial);
Vector(const Vector<T> & v);
~Vector();
unsigned int capacity() const;
unsigned int size() const;
bool empty() const;
iterator begin();
iterator end();
T & front();
T & back();
void push_back(const T & value);
void pop_back(); …Run Code Online (Sandbox Code Playgroud) 让我们假设,我们有一个模板功能:
template<typename T1, typename T2, typename T3>
T3 such_fun(T1 a, T2 b) {
// do something...
}
Run Code Online (Sandbox Code Playgroud)
现在我们想将它用作另一个模板中的参数,例如像那样
template<typename T1, template<typename, typename, typename> some_function>
void big_fun(T1 a) {
// some code...
a = some_function<T1, T1, T1>(a, a);
// some code...
}
Run Code Online (Sandbox Code Playgroud)
可能吗?
我知道我可以使用带有defined()运算符的结构.我只是对功能感到好奇.
编辑:
当我写这个问题时,我的朋友发现了一个部分解决方案:
template<typename T1, T1 (*some_function)(T1, T1)>
void big_fun(T1 a) {
// some code...
a = some_function(a, a);
// some code...
}
Run Code Online (Sandbox Code Playgroud)
但是仍然 - 如果没有在调用之前实现函数类型的实现,我很好奇.例如 - 我可能想要使用各种类型组合调用传递的模板:
template<typename T1, typename T2, template<typename, typename, typename> some_function>
void big_fun(T1 …Run Code Online (Sandbox Code Playgroud) 我继承了一个大量使用模板元编程的项目,现在正处于从Visual Studio 2010升级到2012的过程中.一些模板代码在2012年不再有效.我已经提炼了一个最小的例子:
template <typename T, int i>
class MyClass
{
private:
typedef typename T::Nested<i> Found;
};
Run Code Online (Sandbox Code Playgroud)
给出此错误消息:
source.cpp(5): error C2059: syntax error : '<'
source.cpp(6) : see reference to class template instantiation 'MyClass<T,i>' being compiled
source.cpp(5): error C2238: unexpected token(s) preceding ';'
Run Code Online (Sandbox Code Playgroud)
进一步下来MyClass,我可以使用T::Nested<i>,这只是typedef不起作用.
此示例在2010年编译,但不在2012年编译.此代码有什么问题?
我正在尝试做一些模板元编程,我发现需要"提取"某种类型的某种结构的特化的最高指数.
例如,如果我有一些类型:
struct A
{
template<unsigned int> struct D;
template<> struct D<0> { };
};
struct B
{
template<unsigned int> struct D;
template<> struct D<0> { };
template<> struct D<1> { };
};
struct C
{
template<unsigned int> struct D;
template<> struct D<0> { };
template<> struct D<1> { };
template<> struct D<2> { };
};
Run Code Online (Sandbox Code Playgroud)
那我怎么能写一个像这样的元函数:
template<class T>
struct highest_index
{
typedef ??? type;
// could also be: static size_t const index = ???;
};
Run Code Online (Sandbox Code Playgroud)
给我D一个在上面的任意结构中专门的最高索引,而不 …
c++ templates sfinae template-specialization template-meta-programming
我试图使用c ++模板元编程实现以下功能.我希望建立一个类型列表,然后一起收集这些类型,并在列表上进行进一步的编译时处理.例如:
foo.h中:
class Foo { ... };
// INSERT ANY CODE HERE
Run Code Online (Sandbox Code Playgroud)
bar.h:
class Bar { ... };
// INSERT ANY CODE HERE
Run Code Online (Sandbox Code Playgroud)
main.h:
#include "foo.h"
#include "bar.h"
struct list_of_types {
typedef /* INSERT ANY CODE HERE */ type;
};
Run Code Online (Sandbox Code Playgroud)
我可以在上面的插槽中插入任何代码,只要list_of_types :: type解析为包含类型Foo和Bar的列表的某些表示(例如boost :: mpl :: vector).以下限制适用:
foo.h中的代码不应该知道bar.h中的代码,反之亦然.应该可以在main.h中更改#include指令的顺序,而不是更改任何其他代码.
如果我包含更多类型添加到列表中的标题,则main.h中的代码不应该更改.
类型列表必须在编译时可用.我打算进一步进行涉及清单的元编程.
我有一个属性向量,可以包含不同的类型:
class base_attribute_vector; // no template args
template<typename T>
class raw_attribute_vector : public base_attribute_vector;
raw_attribute_vector<int> foo;
raw_attribute_vector<std::string> foo;
Run Code Online (Sandbox Code Playgroud)
根据类型的运行时输入,我想创建适当的数据结构.伪代码:
std::string type("int");
raw_attribute_vector<type> foo;
Run Code Online (Sandbox Code Playgroud)
显然,这失败了.如果出现以下情况,一个简单但丑陋且难以维护的解决方法是运行时切换/链接:
base_attribute_vector *foo;
if(type == "int") foo = new raw_attribute_vector<int>;
else if(type == "string") ...
Run Code Online (Sandbox Code Playgroud)
我读到了有关仿函数的运行时多态性,但发现它对于概念上容易的任务来说非常复杂.
使这项工作最好,最干净的方法是什么?我玩了boost::hana,发现虽然我可以创建从字符串到类型的映射,但查找只能在编译时完成:
auto types =
hana::make_map(
hana::make_pair(BOOST_HANA_STRING("int"), hana::type_c<int>),
hana::make_pair(BOOST_HANA_STRING("string"), hana::type_c<std::string>)
);
Run Code Online (Sandbox Code Playgroud)
所有可能的类型在编译时都是已知的.任何建议都非常感谢.在一个完美的解决方案中,我将在一个地方创建名称 - >类型映射.之后,我会像这样使用它
std::vector<base_attribute_vector*> foo;
foo.push_back(magic::make_templated<raw_attribute_vector, "int">);
foo.push_back(magic::make_templated<raw_attribute_vector, "std::string">);
foo[0]->insert(123);
foo[1]->insert("bla");
foo[0]->print();
foo[1]->print();
Run Code Online (Sandbox Code Playgroud)
这种魔法不需要在编译时发生.我的目标是拥有尽可能可读的代码.
想象一下,你有几个类,它们都包含一个具有相同含义的静态变量,但它的名称在不同的类中有所不同.
玩具示例:
class Point2D
{
public:
static constexpr int dimension = 2;
private:
double x, y;
}
class Point3D
{
public:
static constexpr int dim = 3;
private:
double x, y, z;
};
Run Code Online (Sandbox Code Playgroud)
我想用一个std::integral_constant孩子包装一个"维度"变量.请注意,我无法编辑'Point'类,因为它们是某些外部库的一部分.这个实现对我有用,但看起来很笨拙(我正在使用VS2017):
template <typename T, typename = void>
struct HasDimensionVar : std::false_type { };
template <typename T>
struct HasDimensionVar<T, decltype( T::dimension, void( ) )> : std::true_type { };
template <typename T, typename = void>
struct HasDimVar : std::false_type { };
template <typename T>
struct HasDimVar<T, decltype( …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个模板来计算编译期间数字的功效(我不是模板元编程专家所以任何评论都表示赞赏).以下是代码:
template<typename T, T X, uint64_t P>
struct Pow
{
static constexpr T result = X * Pow<T,X, P - 1>::result;
};
template<typename T, T X>
struct Pow<T, X, 0>
{
static constexpr T result = 1;
};
template<typename T, T X>
struct Pow<T, X, 1>
{
static constexpr T result = X;
};
Run Code Online (Sandbox Code Playgroud)
我需要称之为:
Pow<decltype(4), 4, 2>::result
Run Code Online (Sandbox Code Playgroud)
问题:有没有办法编写帮助模板,以便呼叫跳过decltype?例如:
Pow<4, 2>::result
Run Code Online (Sandbox Code Playgroud)
在以下情况下,我难以理解推论的工作原理:
template<class Category, Category code>
struct AImpl
{ };
template<class Category, Category code>
struct AHelper
{
using type = AImpl<Category, code>;
};
template<class Category, Category code>
using A = typename AHelper<Category, code>::type;
template<int code>
void doSomething(A<int, code> object)
{
}
Run Code Online (Sandbox Code Playgroud)
以下是测试代码:
A<int, 5> a1;
doSomething(a1); // This does not compile
doSomething<5>(a1); // This compiles
Run Code Online (Sandbox Code Playgroud)
为什么在这种情况下不推导a1?
如果改用以下方式修改A:
template<class Category, Category code>
struct A
{ };
Run Code Online (Sandbox Code Playgroud)
两者都可以。有人知道为什么吗?
[edit]与混合别名和模板专业化相关的问题
c++ templates template-meta-programming c++11 template-argument-deduction