函数专门化基于if模板参数是shared_ptr

Tom*_*asu 4 c++ templates c++11

我正在尝试检测类型是否为a shared_ptr<T>,如果是,则调度到特定的函数模板或覆盖.

这是我实际尝试的简化版本:

#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;
}
Run Code Online (Sandbox Code Playgroud)

它编译得很好,但似乎实际的函数从未实际生成,因为代码没有链接以下错误:

/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
Run Code Online (Sandbox Code Playgroud)

我认为这些将由两个功能模板涵盖.但他们不是.

鉴于此,我似乎对某些事情产生了严重的误解.

所以,如果我解释一下我在/尝试/做什么而不是我实际在做什么,也许会有所帮助.

我有一些"魔术"代码使用一堆新的(对我来说)C++ 11特性将C++代码绑定到lua(可以在这里看到:https://github.com/Tomasu/LuaGlue).有人最近要求支持绑定到包含在其中shared_ptr的类.这不是目前可用的东西,因为它在编译时使用模板和元组解包绑定生成代码以在C++或lua端调用函数.在"神奇"的展开代码中,我有一堆被覆盖的"专用"函数来处理各种变量类型.一些用于基本类型,一个用于静态对象,另一个用于指向对象.A shared_ptr不能以与静态或指针对象相同的方式处理,因此我需要为它们添加一些额外的处理.

例如:

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>());
}
Run Code Online (Sandbox Code Playgroud)

这是实际的代码(通过函数参数注意毛茸茸的模板/覆盖:-x).

我原以为它就像添加另一个addValue函数一样简单,就像我之前的例子中的代码一样enable_if.

zen*_*hoy 6

有什么理由不简单地使用部分专业化?

#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;
}
Run Code Online (Sandbox Code Playgroud)