Use static type from template pointer type
-
Hi,
Le title isn't really clear, but I didn't know how to write it, sorry if it's also a duplicate.
I'm subclassing QAbstractListModel as a template class named AbstractListModel which contains an internal QList (of pointer types). Obviously, my subclass is a template to define the QList content, but I also use it with QVariants.
I want the AbstractListModel subclasses to inherit from *AbstractListModel<MyClass > (which will set the QList content to <MyClass *> also) BUT I'm using the full type (not the pointer, the static type) to convert from QVariant, my problem is that I don't know how to write the full template type from the pointer one.
Example:
@template <typename T = int *>
void test()
{
T a = 0; // Here, a is a pointer to int.
??????? // And here I want to declare an int
}@Is there a way to declare a static type if you know that T is a pointer type?
-
Yes, there is a way in c++ 11, but I don't think it is very useful.
@
template <typename T = int *>
void test()
{
T a = 0; // Here, a is a pointer to int.
auto b = *a; // And here I want to declare an int
std::cout << b << std::endl; // core dump is here :-)
}
@PS: Why not inverse it.
@
template <typename T = int>
void test()
{
T a = 0;
T* b = new T;
std::cout << b << std::endl; // core dump is here :-)
}
@ -
This is just an example. The type will never be an int but a class, and there will be no default type.
I wrote it that way only as a comprehensible example, so inversion is excluded (as the question is how to write the static type from the pointer type), as well as auto ;)
Thanks anyway
-
Thank you for interesting question.
BTW why auto is excluded ?I have another example. But it uses auto
@
/** http://www.cplusplus.com/reference/memory/pointer_traits/- g++ -std=c++11 -o test2 test2.cpp
*/
// pointer_traits example
#include <iostream>
#include <memory>
// using pointer_traits to determine return type:
template <class T>
typename std::pointer_traits<T>::element_type dereference_pointer (T pt) {
return *pt;
}class A
{
public:
A() : m_number(0) {}
~A() {}void setNumber(int number) { m_number = number; } int number() const { return m_number; } private: int m_number;
};
class B
{
public:
B() {}
~B() {}
};int main(int, char**)
{
int* foo = new int(1);
std::shared_ptr<int> bar (new int(2));std::cout << "foo: " << dereference_pointer (foo) << '\n'; std::cout << "bar: " << dereference_pointer (bar) << '\n'; delete foo; A* pa = new A; pa->setNumber(23); auto a = dereference_pointer(pa); a.setNumber(34); std::cout << "pa = " << pa->number() << std::endl; std::cout << "a = " << a.number() << std::endl; B* pb = new B; auto b = dereference_pointer(pb); b.setNumber(34); return 0;
}
@ - g++ -std=c++11 -o test2 test2.cpp
-
[quote author="andreyc" date="1401232860"]BTW why auto is excluded ?
[/quote]
I wrongly thought auto was used to declare ints. So it's not excluded, my mistake.But as I'm reading your post, I think it's still now what I'm asking as I don't think using the value is useful, maybe my question isn't clear.
Let's imagine I have this class:
@template <typename T>
class A
{
T m_dummy;
}@Here, if I instantiate A with T = QWidget * (this is an example), m_dummy will be a pointer to QWidget.
If I instantiate A with T = QWidget, m_dummy will be of type QWidget (the plain type, not a pointer).
Now, my question is: How to write A to be able to instantiate it with T = QWidget * and to have m_dummy to be of type QWidget (the plain type, not the pointer, as is T) ?
Hope it's clearer.
-
Are you sure that you need to declare a variable. Maybe you can use some getter function that will return type auto and compiler will deduce the type.
Could you post an example that reflects your design. -
[quote author="andreyc" date="1401243568"]Could you post an example that reflects your design.[/quote]
What I previously wrote was part of what I need.
@template <typename T>
class A
{
private:
QList<T> m_list;
T m_tmp;
}@Here, if I instantiate A with T = QWidget *, how to write m_tmp to be the plain type and not the pointer?
I wonder how to do it, today I have a solution: Instantiate A with plain type and QList<T>*, but I didn't know how to write it if T = pointer.
-
[quote author="Max13" date="1401266922"]I wonder how to do it, today I have a solution: Instantiate A with plain type and QList<T>*, [/quote]
That I was trying to say when I talking about "inverse it" :-)
[quote author="Max13" date="1401266922"]but I didn't know how to write it if T = pointer.[/quote]I don't know it either. That is why I asked about getter function. With a function you can pass a pointer to a variable and a compiler can deduce the type using
@
template <class T>
typename std::pointer_traits<T>::element_type dereference_pointer (T pt) {
return *pt;
}
@Anyway, I'm glad that you've resolved the issue.
Could you please prepend "[SOLVED]" to the title of your post. So the other good people will be able to find your solution.
-
[quote author="andreyc" date="1401268410"]Could you please prepend "[SOLVED]" to the title of your post.[/quote]
Actually it's not solved ^^'
My own problem is solved, but not "How to write it" :/ -
g++ 4.7.2 compiles it with -std=c++98, got no real idea whether it is in accordance with any standard:
@#include <iostream>template<class T> struct Deref {
typedef T Refed;
};template<typename T> struct Deref<T *> {
typedef T Refed;
};template<typename T> void omg(T t) {
typename Deref<T>::Refed defer(0);
std::cout << defer << std::endl;
}int main() {
omg((int *)NULL);
}@