Determine If Type Is a Pointer in a Template Function

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



Leave a reply



Submit