In a templated class, I would like to make an alias of a variadic parameter, something like:
template<typename ... TYPES>
class X
{
using Types = TYPES;
};
It is easy to make a std::tuple of it, but is there a syntax for doing the above.
The reason is I would like to reference this from the templated class in another class.
Related
I've been reading the chapter 5 of "C++ Templates, The complete guide", and i've seen the concept of "template template" templates, so tried myself.
In a template class, i've declared my template like this:
template <typename TipoClave, typename TipoDato,
template <class Elem, class Alloc = allocator<Elem>> class Lista = vector>
And this works. My problem comes when I try to use a different container than the default.
My class is as follows:
class Tabla
{
public:
struct Celda {
TipoClave clave;
TipoDato dato;
};
Tabla(unsigned tam)
{
t.resize(tam);
}
///< Some other functions
private:
typedef Lista<Celda> ListaDatos;
Lista<ListaDatos> t;
};
And then, when I try to use it from the main program like this:
int main (void)
{
Tabla<string,Alumno,array> tabla(200);
///< Some stuff
return 0;
}
But this line Tabla<string,Alumno,array> tabla(200); does not compile, getting me an error like:
test_tabla_t.cpp: In function ‘int main()’: test_tabla_t.cpp:20:27:
error: type/value mismatch at argument 3 in template parameter list
for ‘template class Lista> class Tabla’ Tabla
tabla(200);
I've tried to use Tabla<string,Alumno,vector> tabla(200);, and it works, so I don't know how to solve this error.
Assuming you're trying to use std::array, it does not take an Allocator template parameter. Its second argument is the size of the array.
template<
class T,
std::size_t N
> struct array;
You haven't mentioned how experienced you are with C++, but since you're trying to learn more, I'll say that I've been using C++ for nearly a decade and can count on one hand the number of times I've used template template parameters.
In this case, you want Lista to be "something that acts like a sequence container[1]", you might like to read about concepts[2], which may make it into C++20. They allow you to tell the compiler the interface you want a template parameter to have.
In the meantime, it might be easier to declare Lista as a plain template parameter.
[1] http://en.cppreference.com/w/cpp/concept/SequenceContainer
[2] https://en.wikipedia.org/wiki/Concepts_(C%2B%2B)
I have a wrapper class that needs to be used interchangeably with the wrapped class.
Fortunately the class and the wrapper are binary compatible (by design) and the conversion can be easily performed (for example in this case by reinterpret_cast, or even simpler as in the example).
In part, to achieve this, I need to be able to convert from the wrapper type to the wrapped type, via operator T().
Currently the code looks like this:
template<class T> // // I am putting this general T type, to show it can be a large (movable) object, for example, std::vector.
struct wrapper{
T a;
operator T const&() const&{return a;} // in other cases it can involve more code, like reinterpret_casts or some conditional blocks.
operator T&&() &&{return std::move(a);} // same
operator T&() &{return a;} // same
};
Can I condense these three conversion functions into one function or less code, or is there another way?
I could make it more general, (but longer code for this simple case) this way,
template<class T>
struct wrapper{
T a;
operator T const&() const&{return a;} // complicated code can be here only
operator T&&() &&{return std::move(operator A&());}
operator T&() &{return const_cast<T&>(operator T const&());}
};
The final objective is that T can be used interchangeably with wrapper<T>.
This is very similar to How do I remove code duplication between similar const and non-const member functions?,
however this case is more specific because 1) it involves the conversion operator and also, 2) involves l-value overloads.
I'm reading the source code of the main json11 header file.
It contains the following declaration:
template <class T, class = decltype(&T::to_json)>
Json(const T & t) : Json(t.to_json()) {}
I'm trying to find some documentation about this usage of decltype and class inside a template declaration but no success.
Does this construction/usage has a name in C++? Any good reference about it?
It's using SFINAE ("Substitution Failure Is Not An Error"), a common technique for advanced template stuff. In this case, it's used as a crude(1) test whether the type T has a function named to_json.
How it works: if the expression T::to_json is well-formed (there is something named to_json inside the type T), decltype(T::to_json) denotes a valid type and the constructor template can be used normally.
However, if T::to_json is ill-formed (i.e. if there is no to_json member inside T), it means substituting the template argument for T has failed. Per SFINAE, this is not an error of the entire program; it just means that the template is removed from further consideration (as if it was never part of the class).
The effect is thus that if type T has a member to_json, you can use an object of type T to initialise a Json object. If there is no such member in T, the constructor will not exist.
(1) I'm saying crude test because this only checks that T has such a member. It doesn't check that the member is a function which can be invoked without arguments and returns something another constructor of Json can accept. A tighter-fitting test might look something like this:
template <class T, class = std::enable_if_t<std::is_constructible<Json, decltype(std::declval<const T>().to_json())>::value>>
Json(const T & t) : Json(t.to_json()) {}
[Live example]
I write a program with my class:
class COrder
{
public:
COrder();
~COrder();
public:
...
CList < CItem > m_oItem;
...
};
which suppose to have list od object of my other class:
class CItem
{
public:
CItem();
~CItem();
public:
int m_i;
double m_d;
CString m_o;
};
and compiler give me error like this in title. Any ideas why ?
In program I use COrder in map:
CMap <CString, LPCTSTR, COrder, COrder> m_map
Quote:
Add copy-constructor and assignment operator to your class COrder.
I add operator= to my class:
COrder& operator=( const COrder oNewOrder )
{
...
m_oItem.AddTail( oNewOrder.m_oItem.GetTail() );
...
return *this;
}
but what you mean by adding "copy-constructor" ?
http://msdn.microsoft.com/en-us/library/ccb3dh5c.aspx i found this but how to implement it in my code. i can't change CList class.
http://www.codeproject.com/Articles/13458/CMap-How-to
Add copy-constructor and assignment operator to your class COrder. This makes the class copyable.
[If class is used in as Key then you need HashKey() and CompareElemenst() in that class]
Also note that STL containers are superior to MFC containers.
You get an error because CMap has default copy-ctor but CMap and CList is derived from CObject and CObject declares private copy constructor and operator=.
So, CMap doesn't offer a copy semantic "out of the box".
I would suggest you to use STL std::map container, which is designed in a
way to implement copy semantic out-of-the-box.
What you don't have with STL out of the box is serialization only.
Note that std::map does not have the confusing ARG_KEY and ARG_VALUE
templates.
std::map just has the Key and Type template arguments (in its basic form).
http://msdn.microsoft.com/en-us/library/s44w4h2s%28VS.80%29.aspx
Or else you can go by the pointer way as Ajay suggested by which you will just shut up the compiler.
The problem statement:
CList<CItem> m_oItem;
And the trigger statement (or some usage):
CMap <CString, LPCTSTR, COrder, COrder> m_map;
Why? Well, CMap would call copy constructor and/or assignment operator for COrder. You didn't provide any, but compiler provides them from your class (i.e. for COrder). This class contains a CList object, which is inherited from CObject. CObject doesn't provide (or better say: Prevents) copy-constructor or assignment operator.
As a result, the compiler raises the error. Unfortunately, the (bad) compiler doesn't give you back-trace of this error.
Best bets for as the solution:
CList < CItem* > m_oItem;
CList<CItem> *m_poItem;
Use or implement your own collection.
I'm trying to create an iterator which only can dereference to real value types, not to references.
Is this possible using boost::iterator_facade, or does it require me to have values that can be returned by adress\reference.
To be more specfic, my iterator returns a std::pair of references, which means my iterators value_type is not stored anywhere, but created on the fly on dereferencing (like std::map::iterator).
Yes, thing you want is possible. Please, take a look at boost/iterator_facade.hpp (example is for Boost lib of version 1.49.0 but it is ok for its new distributions also):
template <
class Derived
, class Value
, class CategoryOrTraversal
, class Reference = Value&
, class Difference = std::ptrdiff_t
>
class iterator_facade
Template argument Reference is the key. You should just specify Reference when deriving from boost::iterator_facade. For example, your code can look like as the following:
template<typename value_type>
class custom_iterator
: public boost::iterator_facade<
custom_iterator<value_type>,
value_type,
boost::forward_traversal_tag,
value_type
>
{
...
value_type dereference() const{ return value_type(...); }
...
};