How can I detect that a template is of pointer type?
namespace Linked{
template <class T>
struct Nodo{
T Element;
Nodo<T> *Next = nullptr;
~Nodo(){
if constexpr (std::is_pointer<T>::value)
delete Element;
}
};
You should also consider if T is pointer to array.
Template detects if T is pointer or class
You can use a combination of std::is_pointer
and std::enable_if
:
#include <type_traits>
#include <iostream>
class MyClass
{
};
template <typename Object>
class List
{
public:
template<class T=Object>
void insert(T t, typename std::enable_if<std::is_pointer<T>::value >::type* = 0)
{
std::cout << "insert pointer" << std::endl;
}
template<class T=Object>
void insert(T t, typename std::enable_if<!std::is_pointer<T>::value >::type* = 0)
{
std::cout << "insert non-pointer" << std::endl;
}
};
int main()
{
MyClass a;
List<MyClass> lst;
List<MyClass*> plst;
lst.insert(a);
plst.insert(new MyClass());
return 0;
}
Live example: https://ideone.com/CK8Zdo
This will allow you to insert both pointers and non-pointers into a pointer or non-pointer list.
If you want to restrict that, you can use this:
#include <type_traits>
#include <iostream>
class MyClass
{
};
template <typename Object>
class List
{
public:
template<class T=Object>
void insert(T t, typename std::enable_if<std::is_same<T,Object>::value&&std::is_pointer<T>::value >::type* = 0)
{
std::cout << "insert pointer" << std::endl;
}
template<class T=Object>
void insert(const T& t, typename std::enable_if<std::is_same<T,Object>::value&&!std::is_pointer<T>::value >::type* = 0)
{
std::cout << "insert non-pointer" << std::endl;
}
};
int main()
{
MyClass a;
List<MyClass> lst;
List<MyClass*> plst;
lst.insert(a);
// plst.insert(a); // compiler error
// lst.insert(new MyClass()); // compiler error
plst.insert(new MyClass());
return 0;
}
Live example: https://ideone.com/3DtBfr
Determine if template argument is a pointer
If the compiler supports C++11 use std::is_pointer
:
#include <iostream>
#include <type_traits>
template <typename T>
class MyTem
{
public:
static const bool IS_POINTER = std::is_pointer<T>::value;
};
int main()
{
std::cout << MyTem<char*>::IS_POINTER << "\n";
std::cout << MyTem<char>::IS_POINTER << "\n";
return 0;
}
See demo http://ideone.com/Mo394 .
C++ -- determine if generic variable is a pointer
1) Determine if Type is a pointer in a template function
2) How would you know if that pointer is pointing to dynamically allocated memory?
C++ whether a template type is a pointer or not
That is a handy utility, but I think it's better just to get used to assigning NULL
after using native delete
.
To get a function that only is considered for modifiable pointer type arguments, use
template< typename T > // The compiler may substitute any T,
void delete_ref( T *&arg ); // but argument is still a pointer in any case.
To simply find out whether a type is a pointer, use is_pointer
from <type_traits>
in Boost, TR1, or C++0x.
Pointer level return type based on template function arguments
you cannot declare m
and return type as T*
since it is not in multiple dimension.
template<typename T, typename size_type>
auto mat(size_type size){return new T[size];}
template<typename T, typename size_type, typename... size_types>
auto mat(size_type size, size_types... sizes){
using inner_type = decltype(mat<T>(sizes...));
inner_type* m = new inner_type[size];
for(int j = 0; j < size; j++){
m[j] = mat<T>(sizes...);
}
return m;
}
Accessing a member in a template: how to check if the template is a pointer or not?
You could use a simple pair of overloaded function templates:
template<typename T>
T& access(T& t) { return t; }
template<typename T>
T& access(T* t) { return *t; }
And then use them this way:
access(val).member = 42;
For instance:
template<typename T>
struct A
{
void do_it(T& val)
{
access(val).member = 42;
}
};
struct Type
{
int member = 0;
};
#include <iostream>
int main()
{
A<Type> a;
Type t;
a.do_it(t);
std::cout << t.member << std::endl;
A<Type*> a2;
Type* t2 = new Type(); // OK, I don't like this, but just to show
// it does what you want it to do...
a2.do_it(t2);
std::cout << t2->member;
delete t2; // ...but then, don't forget to clean up!
}
Here is a live example.
Can we write a function which returns a function pointer to a function template?
No you cannot return a pointer to a function template, because a function template is not a function. It is a template.
// static auto GetPtr() { return X1::Do; } // how to write such a function?
You need &
to get a pointer to a member function, though Do
is not a member function it is a member function template. You could return a pointer to X1::Do<int>
or to X1::Do<double>
but there is no pointer to X1::Do
.
You can however return a functor with an overloaded call operator and that operator can be a template:
struct foo {
template <typename T>
void operator()(const T& t) {}
void operator()(int x){}
};
foo magic() { return foo{}; }
int main() {
magic()(3); // calls operator()(int)
magic()("hello world"); // calls operator()<const char[12]>
}
After rereading your question and the Q&A you link, I think you are maybe looking for this:
#include <iostream>
struct X1 {
static void Do(auto n) { std::cout << "1" << n << std::endl; }
static auto GetPtr() { return &X1::Do<int>; }
};
struct X2 {
static void Do(int n) { std::cout << "2" << n << std::endl; }
static auto GetPtr(){ return &Do; }
};
template <typename T> T magic(bool b, T t1, T t2) { return b ? t1 : t2; }
int main() {
auto l1 = magic( true, X1::GetPtr(), X2::GetPtr() );
l1(100);
}
As stated above, you cannot get a member function pointer to X1::Do
but you can get a pointer to X1::Do<int>
.
And as you are refering to conversion of lambdas to function pointers: Also lambdas with auto
argument can only be converted to function pointers after choosing the argument type. Consider the example from cppreference:
void f1(int (*)(int)) {}
void f2(char (*)(int)) {}
void h(int (*)(int)) {} // #1
void h(char (*)(int)) {} // #2
auto glambda = [](auto a) { return a; };
f1(glambda); // OK
f2(glambda); // error: not convertible
h(glambda); // OK: calls #1 since #2 is not convertible
int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK
It is not possible to get a pointer to function of type auto(auto)
(it isn't a type of a function to begin with). In all the calls above, after the conversion there is no auto
anymore. Instead the requested type is deduced and a conversion to the respective function pointer is done.
c++ passing a pointer to a template function as template
Your iter
function template requires a function for its third template parameter; but print
(on its own) is not a function – it's a function template, and the compiler simply cannot deduce what template parameter to use in order to actually create a function … so you need to tell it! Just add the type of the tab
array/pointer as that template parameter:
int main()
{
int tab[] = { 5,4,3,2,1 };
iter(tab, 5, print<int>);
return 0;
}
Related Topics
Do Child Threads Exit When the Parent Thread Terminates
Should I Delete the Move Constructor and the Move Assignment of a Smart Pointer
Why Use Precompiled Headers (C/C++)
Cmake - Remove a Compile Flag for a Single Translation Unit
Return Type Covariance with Smart Pointers
Differencebetween a MACro and a Const in C++
How to Open a Gstreamer Pipeline from Opencv with Videowriter
Differencebetween the /Ox and /O2 Compiler Options
Why Does C++11 Have 'Make_Shared' But Not 'Make_Unique'
Difference Between Creating Object with () or Without
Constexpr Const VS Constexpr Variables
Difference Between Enum and Define Statements
Variable Number of Parameters in Function in C++
What Is a Buffer Overflow and How to Cause One
Boost::Asio - How to Interrupt a Blocked Tcp Server Thread
Do I Need to Protect Read Access to an Stl Container in a Multithreading Environment