I have templated class vector<typename T,size S> (I have to use this instead of std::vector). I would like to specify an alias which is in type ofvector<double,2> , but I also need to count the amount of all created and all currently live objects of this. Here's fragment of my templated class:
template<typename T, size S>
class vector{
private:
T *_values;
public:
vector():
_values(new T[S]){
for(int i =0; i < S; i++)
_values[i] = T();
}
~vector(){
delete[] _values;
}
};
So I thought about creating class named vector2D which inherits vector<double,2> and with two additional static variables to count its amounts. But how to do that? How to invoke superclass constructor and destructor so that it only contains incrementation/decrementation of these two static variables? vector2D is going to be used often in project I have to do. Maybe there is better solution?
P.S How to pretty initialize *_values? I tried *_values = { 0 } but it didn't work (of course assuming this is going to be a table of primitive types).
I would like to specify an alias which is in type of vector<double, 2>
Well that's simple:
typedef vector<double, 2> vector2D
but I also need to count the amount of all created and all currently live objects of this.
That's simple as well. Here's a small example:
#include <iostream>
template <typename T, int S>
class vec {
public:
vec() {
++obj_counter;
}
static int obj_counter;
};
template <typename T, int S>
int vec<T, S>::obj_counter = 0;
typedef vec<double, 2> vec2d;
int main() {
vec<int, 1> intvec1;
vec<int, 1> intvec12;
vec2d doublevec2;
std::cout << vec2d::obj_counter << std::endl;
return 0;
}
The advantage of this is the fact that obj_counter works for every type. In the above example if you type:
std::cout << vec<int, 1>::obj_counter << std::endl;
It will print 2.
Related
I'm writing a class with a function that is repeatedly called and decided to implement this as giving the function as template parameter.
As a concrete example of what I'm talking about, consider the following class:
#include <array>
template<double (*func)(std::array<double,3>)>
class MyClass
{
public:
MyClass()
{
std::array<double,3> v {{0.1,0.2,0.1}};
func(v);
}
};
which can then be instantiated with a function, as for example:
double func(std::array<double,3> x)
{
return x[0]*x[0]+x[1];
}
int main()
{
MyClass<func> entity;
}
However, I need the function to be callable with different types (the operations in the function are of course applicable to all of them), that is I want to have this function templated, as in:
template<typename scalartype, typename vectype>
scalartype func1(vectype x)
{
scalartype res = x[0]*x[0]+x[1];
return res;
}
I can still use this as template parameter, but the function parameter and return type are then fixed in the class. So how can I have the function as templated function available in the class? Such that I can, for example, call it with an std::vector of four integers and have an integer returned.
I tried using template template parameters, but I can't even figure out how to use two template parameters with them (as they only seem to allow the template ... syntax). I'm sorry if this is formulated unclearly, I am still a newcomer.
You can put your template function in a class, and then pass in that class to MyClass.
#include <iostream>
#include <vector>
#include <array>
struct templateHolder {
template <typename vectype, typename scalartype = typename vectype::value_type>
static scalartype func(vectype x) {
return x[0] + x[1];
}
};
template<typename T>
class MyClass
{
public:
MyClass()
{
std::vector<int> vec {1,2};
std::cout << T::func(vec) << std::endl;
std::array<double, 2> arr {0.5, 3.33};
std::cout << T::func(arr) << std::endl;
}
};
int main() {
MyClass<templateHolder> foo;
return 0;
}
I chose to deduce scalartype from vectype. Not necessarily what you want but it could be an option depending on your use-case.
I am trying to build a constructor to take an array as an argument which overloads another who take a scalar instead. Code is below.
#include <iostream>
template <typename T>
class SmallVec { // This is a 3 dimensional vector class template
public:
T data[3] = {0}; // internal data of class
template <typename U>
explicit SmallVec(const U& scalar) { // if a scalar, copy it to each element in data
for(auto &item : data) {
item = static_cast<T>(scalar);
}
}
template <typename U>
explicit SmallVec(const U* vec) { // if a vector, copy one by one
for(auto &item : data) {
item = static_cast<T>(*vec);
vec++;
}
}
};
int main() {
float num = 1.2;
float *arr = new float[3];
arr[2] = 3.4;
SmallVec<float> vec1(num); // take num, which works fine
SmallVec<float> vec2(arr); // !!!--- error happens this line ---!!!
std::cout << vec1.data[2] << " " << vec2.data[2] << std::endl;
return 0;
}
The compiler complains that
error: invalid static_cast from type 'float* const' to type 'float'
Obviously, vec2(arr) still calls the first constructor. However, if I remove template <typename U> and replace U to T. The program just works fine. What should I do to correct this?
Any suggestions are appreciated!
Here's how to use SFINAE to get what you want:
#include <vector>
#include <map>
#include <string>
using namespace std;
template<class T>
struct Foo {
template <class U, typename enable_if<is_pointer<U>::value, int>::type = 0>
Foo(U u){}
template <class U, typename enable_if<!is_pointer<U>::value, int>::type = 0>
Foo(U u){}
};
int main()
{
Foo<int> f('a'); // calls second constructor
Foo<int> f2("a"); // calls first constructor
}
live: https://godbolt.org/g/ZPcb5T
I am trying to build a constructor to take an array as an argument
(...)
explicit SmallVec(const U* vec) { // if a vector, copy one by one
You do not take an array. You take a pointer, which may or may not point to an array, and even if it points to an array, who says that the array has at least three elements? That's a serious design flaw.
C++ does allow you to take raw arrays by reference or const reference, even though the syntax is horrible:
explicit SmallVec(const U (&vec)[3]) {
The implementation of the constructor is then also different:
for(int index = 0; index < 3; ++index) {
data[index] = static_cast<T>(vec[index]);
}
Looking at main, however, the problem goes deeper. You use new[] to allocate an array dynamically. That's already a very bad idea. Coincidentally, your example also misses a delete[]. Why don't you use a local array instead?
float arr[3];
This will make your program compile and probably run correctly, but there's still undefined behaviour in your code, because you only set the 3rd element of the array to a valid value; the other two elements remain uninitialised, and reading from an uninitialised float, even if you just copy it, formally results in undefined behaviour.
So better make it:
float arr[3] = { 0.0, 0.0, 3.4 };
In addition to that, C++11 invites you to use std::array, which generally makes things a bit safer and improves the syntax. Here is a complete example:
#include <iostream>
#include <array>
template <typename T>
class SmallVec { // This is a 3 dimensional vector class template
public:
std::array<T, 3> data; // internal data of class
template <typename U>
explicit SmallVec(const U& scalar) { // if a scalar, copy it to each element in data
for(auto &item : data) {
item = static_cast<T>(scalar);
}
}
template <typename U>
explicit SmallVec(std::array<U, 3> const& vec) { // if a vector, copy one by one
for(int index = 0; index < 3; ++index) {
data[index] = static_cast<T>(vec[index]);
}
}
};
int main() {
float num = 1.2;
std::array<float, 3> arr = { 0.0, 0.0, 3.4 };
SmallVec<float> vec1(num);
SmallVec<float> vec2(arr);
std::cout << vec1.data[2] << " " << vec2.data[2] << std::endl;
return 0;
}
Even though both constructors use the explicit specifier and try to avoid type conversions you should note that the first is just as good a candidate as the second. If you substitute U for float* you will get:
explicit SmallVec(const float*& scalar)
which is totally acceptable and will explain the compilation error.
You could resolve the problem by changing the second constructor to:
template <typename U>
explicit SmallVec(U* const vec) { // if a vector, copy one by one
U* local = vec;
for(auto &item : data) {
item = static_cast<T>(*local);
local++;
}
}
However, I suggest an even more explicit way:
class ScalarCopy {};
class VectorCopy {};
...
template <typename U>
SmallVec(const U& vec, ScalarCopy);
template <typename U>
SmallVec(const U* const vec, VectorCopy);
and make explicit calls:
SmallVec<float> vec1(num, ScalarCopy());
SmallVec<float> vec2(arr, VectorCopy());
I have this class:
typedef vector<Eigen::Affine3d,Eigen::aligned_allocator<Eigen::Affine3d> > VoteList;
template <class T>
class KernelDensityEstimator {
public:
KernelDensityEstimator() {}
void setData(vector<T>& d) {
data = d;
}
void setKernel(double (*k)(T&, T&)) {
kernel = k;
}
double evaluate(T& p) {
double sum;
for (int i = 0; i < data.size(); i++) {
sum += (*kernel)(p, data[i]);
}
return sum/data.size();
}
private:
double (*kernel) (T&, T&);
vector<T> data;
};
I want to use with with the type T = Eigen::Affine3d for now. However, when I call setData() it's causing me troubles because Eigen requires to specify an Eigen::aligend_allocator for std containers to use with Eigen.
So when I give a vector<Eigen::Affine3d,Eigen::aligned_allocator<Eigen::Affine3d> > (aka VoteList) as the input parameter to setData() my compiler complaines that:
no known conversion for argument 1 from ‘VoteList {aka std::vector<Eigen::Transform<double, 3, 2>, Eigen::aligned_allocator<Eigen::Transform<double, 3, 2> > >}’ to ‘std::vector<Eigen::Transform<double, 3, 2>, std::allocator<Eigen::Transform<double, 3, 2> > >&’
Which kind of makes sense, but I thought that the allocator is part of the object type. Is there a way around this and keeping my KernelDensityEstimator generic?
You can enable Eigen's std::vector specializations for the types you are planing to use, as detailed there, e.g.:
#include<Eigen/StdVector>
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Affine3d)
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Matrix4d)
...
You basically want to have a different type for your member data depending on the class template parameter type T. There are several ways to do that, here is one suggestion:
Define a special storage type for your class, in which you keep the data (best put it in a suitable namespace or inside your class):
//normal storage type
template<typename T>
struct storage_type_impl
{
using type = std::vector<T>;
};
//storage type for Eigen::Transform types
template<typename ... Args>
struct storage_type_impl<Eigen::Transform<Args ...> >
{
using type = std::vector<Eigen::Transform<Args ...>
, Eigen::aligned_allocator<Eigen::Transform<Args ...> > >;
};
template<typename T>
using storage_type = typename storage_type_impl<T>::type;
Now you can use that inside your class, together with a templated setData method (that is sufficient as the compiler will still complain if it cannot perform the data copy/move):
template <class T>
struct KernelDensityEstimator
{
template<typename D>
auto setData(D&& d)
{
data = std::forward<D>(d); //calls move assignment if d is an rvalue
//otherwise a copy is performed
}
//...
private:
storage_type<T> data;
//...
};
The code is untested as I don't have Eigen available at the moment, but I hope it's still able to explain the basic idea.
I have a class-template representing a mathematical vector:
template<class Value_T, unsigned int N>
class VectorT
{
public:
void Normalize()
{
// normalize only double/float vectors here
}
private:
// elements in the vector
value_type elements[N];
// the number of elements
static const size_type size = N;
};
I would like to have a special treatment for vectors of integer types, as a vector normalization is not possible on this types. So I need a seperate (may be specialization) for the Normalize method that depends on the template argument Value_T of the VectorT class-template.
I have tried to use template specialization in different ways but did not get it to work. Do I have to make the Normalize function a template function itself? At the moment it just a normal member-method.
You can solve this with a tag dispatching technique:
#include <iostream>
#include <type_traits>
template<class Value_T, unsigned int N>
class VectorT
{
public:
void Normalize()
{
using tag = std::integral_constant<bool
, std::is_same<Value_T, double>::value
|| std::is_same<Value_T, float>::value>;
// normalize only double/float vectors here
Normalize(tag());
}
private:
void Normalize(std::true_type)
{
std::cout << "Normalizing" << std::endl;
}
void Normalize(std::false_type)
{
std::cout << "Not normalizing" << std::endl;
}
// elements in the vector
Value_T elements[N];
// the number of elements
static const std::size_t size = N;
};
DEMO
It seems that you want forbid Normalize for other type than floating point, so you may use static_assert to have good error message:
template<class Value_T, unsigned int N>
class VectorT
{
public:
void Normalize()
{
static_assert(std::is_floating_point<Value_T>::value, "Normalize available only for floating point");
// normalize only double/float vectors here
}
// Other stuff
};
Also you can use std::enable_if<>
#include <iostream>
#include <type_traits>
template<class Value_T>
class VectorT
{
public:
template<class T = Value_T>
typename std::enable_if<std::is_integral<T>::value, void>::type
Normalize()
{
std::cout << "Not normalizing" << std::endl;
}
template<class T = Value_T>
typename std::enable_if<!std::is_integral<T>::value, void>::type
Normalize()
{
std::cout << "Normalizing" << std::endl;
}
};
int main()
{
VectorT<int> vint;
VectorT<double> vdouble;
vint.Normalize();
vdouble.Normalize();
return 0;
}
DEMO
Yes, you can independently specialize a specific member function of a template class. However, function templates (including member function templates) do not allow partial specializations. Function templates only support explicit specializations. An explicit specialization in your case that would look as follows
// Header file
template<class Value_T, unsigned int N>
class VectorT
{
public:
void Normalize()
{
// normalize only double/float vectors here
}
...
};
// Declare an explicit specialization for <int, 5>
template <> void VectorT<int, 5>::Normalize();
and then
// Implementation file
// Define the explicit specialization for <int, 5>
template <> void VectorT<int, 5>::Normalize()
{
...
}
However, explicit initialization is not what you need, apparently, since you want to "fix" the type only and leave the size flexible, i.e. you need a partial specialization. This can be done using the std::enable_if functionality of C++11 (as shown in other answers) as well as through some basic tricks of C++98.
Of course if your class is relatively lightweight, i.e. it does not have much generic code besides that Normalize, you can simply partially specialize the whole class. It will take just a bit more typing.
The X: What I want to do:
I have the types: BaseType and DerivedType<int k> (see code below), and I need to handle a collection of K vectors of the derived types std::vector<DerivedType<k>>, k = 1...K. I'd like to access the objects in these vectors, and perform an operation on them that depends on k. K is a compile time constant. The problem is illustrated in the implementation:
The types are defined as:
#include <iostream>
#include <algorithm>
struct BaseType { // Interface of the DerivedTypes
virtual void print(){std::cout << "BaseType!" << std::endl; }
};
template< int k >
struct DerivedType : public BaseType {
static const int k_ = k;
// ... function calls templated on k ...
void print(){std::cout << "DerivedType: " << k_ << std::endl;}
};
template< int k >
void doSomething ( DerivedType<k>& object ) { object.print(); }
And what I want to do is:
int main() {
// My collection of vectors of the derived types:
std::vector<DerivedType<0>> derType0(2);
std::vector<DerivedType<1>> derType1(1);
std::vector<DerivedType<2>> derType2(3);
// ... should go to K: std::vector<DerivedType<K>> derTypeK;
// Iterate over the derived objects applying a k-dependent templated function:
std::for_each(begin(derType0),end(derType0),[](DerivedType<0>& object){
doSomething<0>(object);
});
std::for_each(begin(derType1),end(derType1),[](DerivedType<1>& object){
doSomething<1>(object);
});
std::for_each(begin(derType2),end(derType2),[](DerivedType<2>& object){
doSomething<2>(object);
});
return 0;
}
I want to avoid repeating code, such that I only have to change K, which is a compile time constant of O(10). Ideally, I would have something "more like" this:
// Pseudocode: do not try to compile this
create_derived_objects(DerivedType,K)
= std::vector< std::vector<DerivedType<k>>* > my_K_derived_types;
for each vector<DerivedType<k>>* derivedTypes in my my_K_derived_types
for each object in (*derivedTypes)
doSomething<k> on object of type derivedType<k>
// I could also restrict doSomething<k> to the base interface
Each vector of derived types contains O(10^6) to O(10^9) objects. The inner-most loops are the most time consuming part of my application making dynamic_cast only an option for the outer-most loop.
The Y: what I have tryed without succes.
I am at the moment studying the Abrahams C++ Template Metaprogramming book to see if I could use boost::mpl. I am also doing the tutorials on boost::fusion to see if I could use it too. However, the learning curve of these libraries is rather large, so I wanted to ask first before I invest a week in something when a better and simpler solution is available.
My first try was to wrapp my vectors std::vector<DerivedType<k>> such that I can create a vector<WrappedDerivedTypes*>, and access each of the single vectors separately within a for_each loop. However, in the loop I have a series of if(dynamic_cast<std::vector<DerivedType<0>>>(WrappedVector) != 0 ){ do for_each loop for the derived objects } else if( dynamic_cast...) { do...} ... that I wasn't able to eliminate.
What about a recursive solution based on a generic linked list of vectors, a strategy pattern and a thing that applies strategies recursively through the linked list? (note: see the improved version at the end):
#include <iostream>
#include <vector>
template <int j>
class holder {
public:
const static int k = j;
};
template <int j>
class strategy {
public:
void operator()(holder<j> t)
{
std::cout << "Strategy " << t.k << std::endl;
}
};
template <int k>
class lin_vector {
private:
std::vector<holder<k>> vec;
lin_vector<k-1> pred;
public:
lin_vector(const lin_vector<k-1> &pred, std::vector<holder<k>> vec)
: vec(vec), pred(pred) { }
std::vector<holder<k>> get_vec() { return vec; }
lin_vector<k-1> &get_pred() { return pred; }
};
template <>
class lin_vector<0> {
public:
lin_vector() { }
};
template <int k, template <int> class strategy>
class apply_strategy {
public:
void operator()(lin_vector<k> lin);
};
template <int k, template <int> class strategy>
void apply_strategy<k, strategy>::operator()(lin_vector<k> lin)
{
apply_strategy<k-1, strategy>()(lin.get_pred());
for (auto i : lin.get_vec())
strategy<k>()(i);
}
template <template <int> class strategy>
class apply_strategy<0, strategy>
{
public:
void operator()(lin_vector<0> lin) { /* does nothing */ }
};
template <int k>
lin_vector<k> build_lin()
{
return lin_vector<k>(build_lin<k-1>(), {holder<k>()});
}
template <>
lin_vector<0> build_lin()
{
return lin_vector<0>();
}
int main(void)
{
apply_strategy<5, strategy>()(build_lin<5>());
}
Compile it with a C++11 compiler.
Most probably you'll find unsatisfactory the fact that building a lin_vector requires a lot of copying, but you can specialize the structure to suit your needs (perhaps substituting the pred with a pointer or embedding the creation strategy straight into the linked list).
EDIT: here there is an improved version which avoids a lot of copying and handles list building and processing in a more coherent and uniform way:
#include <iostream>
#include <vector>
template <int j>
class holder {
public:
const static int k = j;
};
template <int k>
class lin_vector {
private:
std::vector<holder<k>> vec;
lin_vector<k-1> pred;
public:
std::vector<holder<k>> &get_vec() { return vec; }
lin_vector<k-1> &get_pred() { return pred; }
};
template <>
class lin_vector<0> {
public:
lin_vector() { }
};
template <int k, template <int> class strategy>
class apply_strategy {
public:
void operator()(lin_vector<k> &lin);
};
template <int k, template <int> class strategy>
void apply_strategy<k, strategy>::operator()(lin_vector<k> &lin)
{
apply_strategy<k-1, strategy>()(lin.get_pred());
strategy<k>()(lin.get_vec());
}
template <template <int> class strategy>
class apply_strategy<0, strategy>
{
public:
void operator()(lin_vector<0> &lin) { /* does nothing */ }
};
template <int j>
class strategy {
public:
void operator()(std::vector<holder<j>> &t)
{
std::cout << "Strategy " << j << ", elements: ";
for (auto v : t)
std::cout << v.k << " ";
std::cout << std::endl;
}
};
template <int j>
class build_strategy {
public:
void operator()(std::vector<holder<j>> &t)
{
for (unsigned int i = 0; i < j; i++)
t.push_back(holder<j>());
}
};
int main(void)
{
const int K = 5;
lin_vector<K> list;
apply_strategy<K, build_strategy>()(list);
apply_strategy<K, strategy>()(list);
}
A solution free of virtual dispatch is possible, though it's probably overkill.
The first thing you need is a function template doSomething<K>() that you specialise on each derived type:
template <int K>
void doSomething(vector<DerivedType<K> >& x);
template <>
void doSomething<1>(vector<DerivedType<1> >& x) { ... }
template <>
void doSomething<2>(vector<DerivedType<2> >& x) { ... } // etc.
You could then build a strongly-typed collection of vectors using a recursively defined struct template:
template <int K>
struct vov {
vov<K - 1> prev;
vector<DerivedType<K> > v;
};
template <>
struct vov<1> {
vector<DerivedType<1> > v;
};
Finally, you can write a recursive function template to process this structure:
template <int K>
void process(vov<K>& x) {
doSomething(x.v); // Type inference will find the right doSomething()
process(x.prev); // Here too
}
template <>
void process<1>(vov<1>& x) {
doSomething(x.v);
}
Now the main code will look like:
vov<42> foo;
process(foo);
Because the process() function call performs iteration through the use of recursion, it will probably use K stack frames unnecessarily; however it is tail recursion, which modern optimising C++ compilers can usually convert into plain iteration with no stack wastage. Using tail recursion forces us to process the vectors in "reverse" order, so that the DerivedType<1> vector is processed last, but if necessary this could be fixed with a slightly more elaborate template using 2 int template parameters (one will "count up" towards the other, instead of a single int parameter that "counts down" towards 1).
Observe that there is no benefit gained by deriving each DerivedType<k> from BaseType in this solution -- you may as well forget about BaseType altogether, unless you need it for a different reason.
There may well be MPL primitives that simplify some of these processes -- if anyone knows them, please feel free to edit.