I'm trying to detect if a type is a shared_ptr<T>
and if it is, dispatch to a specific function template or override.
Here's a simplified version of what I'm actually attempting:
#include <type_traits>
#include <memory>
#include <cstdio>
template <class T> struct is_shared_ptr : std::false_type {};
template <class T> struct is_shared_ptr<std::shared_ptr<T> > : std::true_type {};
class Foo { };
typedef std::shared_ptr<Foo> SharedFoo;
template<class T> void getValue();
template<class T, typename std::enable_if<is_shared_ptr<T>::value>::type = 0>
void getValue()
{
printf("shared!\n");
}
template<class T, typename std::enable_if<!is_shared_ptr<T>::value>::type = 0>
void getValue()
{
printf("not shared!\n");
}
int main(int, char **)
{
getValue<SharedFoo>();
getValue<Foo>();
return 0;
}
It compiles just fine, but it seems the actual functions were never actually generated because the code doesn't link with the following errors:
/tmp/ccjAKSBE.o: In function `main':
shared_test.cpp:(.text+0x10): undefined reference to `void getValue<std::shared_ptr<Foo>>()'
shared_test.cpp:(.text+0x15): undefined reference to `void getValue<Foo>()'
collect2: error: ld returned 1 exit status
I would think that those would be covered by the two function templates. But they aren't.
Given that, it seems I am seriously misunderstanding something.
So maybe it would help if I explain what I'm /trying/ to do rather than what I'm actually doing.
I have some "magic" code using a bunch of new (to me) C++11 features to bind C++ code to lua (can be seen here: https://github.com/Tomasu/LuaGlue). someone has recently asked for support for binding to classes wrapped in shared_ptr
's. which is not something that works at the moment, because it binds at compile time using templates and tuple unwrapping to generate code to call functions on either the C++ or lua side. In the "magic" unwrapping code, I have a bunch of overridden and "specialized" functions that handle various variable types. Some for basic types, one for static objects, and another for pointer to objects. A shared_ptr
can't be handled in the same way as either a static or pointer object, so I need to add some extra handling just for them.
For example:
template<typename T>
T getValue(LuaGlue &, lua_State *, unsigned int);
template<>
int getValue<int>(LuaGlue &, lua_State *state, unsigned int idx)
{
return luaL_checkint(state, idx);
}
template<class T>
T getValue(LuaGlue &g, lua_State *state, unsigned int idx)
{
return getValue_<T>(g, state, idx, std::is_pointer<T>());
}
That's the actual code (notice the hairy template/override via function argument :-x).
I had thought it'd be as simple as adding another addValue
function, along the lines of the code in my earlier example, via enable_if
.
Any reason not to simply use partial specialization?
#include <type_traits>
#include <memory>
#include <cstdio>
class Foo { };
typedef std::shared_ptr<Foo> SharedFoo;
template <class T>
struct getValue {
getValue() {
printf("not shared!\n");
}
};
template <class T>
struct getValue<std::shared_ptr<T> > {
getValue() {
printf("shared!\n");
}
};
int main(int, char **)
{
getValue<SharedFoo>();
getValue<Foo>();
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With