c++ - boost::tuple 和通用结构的不同模板特化

标签 c++ templates boost

我迷失了模板。

我在标题中有这段代码:

void push(lua_State *, bool);
void push(lua_State *, int);
void push(lua_State *, long);
void push(lua_State *, unsigned long);
void push(lua_State *, lua_Number);
void push(lua_State *, lua_CFunction);
void push(lua_State *, const char *);
void push(lua_State *, const char *, std::size_t);
void push(lua_State *, const std::string &);

template<typename T>
void push(lua_State * L, const std::vector<T> & value)
{
    lua_newtable(L);
    std::size_t size = value.size();
    for(unsigned int i = 0; i < size; i++)
    {
        lua_pushinteger(L, i + 1);
        push(L, value[i]);
        lua_settable(L, -3);
    }
}

inline void push(lua_State *, boost::tuples::null_type){}
inline void push(lua_State *, boost::tuple<>){}

template<typename HT, typename TT>
void push(lua_State * L, const boost::tuples::cons<HT, TT> & value){
    push(L, value.get_head());
    push(L, value.get_tail());
}

//Declared but not defined. *Intentional* compile-time error if trying to push a Luaproxy (undefined reference). Use Lua stack reference instead
template<typename T>
void push(lua_State* l, Luaproxy<T>& value);

template<typename T>      //most generic version
void push(lua_State* l, T& value){
    Luaproxy<T>::new_c(l, value, false);
}

我希望看到 boost::tuples::cons push() 的版本当作为第二个参数传递 boost::make_tuple(...) 的结果时调用.但是我在链接时遇到错误,表明此类调用已解析为最通用版本的 push , 即 push(lua_State* l, T& value) .

最后的结果是我一定能做到

mystruct example;
push(l, boost::make_tuple(3, 4, example))

而且这个必须依次调用

void push(lua_State * L, const boost::tuples::cons<HT, TT> & value)  //tuple contains int, int, mystruct
void push(lua_State *, int)
void push(lua_State * L, const boost::tuples::cons<HT, TT> & value)  //my tuple contains int mystruct
void push(lua_State *, int)
void push(lua_State * L, const boost::tuples::cons<HT, TT> & value)  //my tuple contains mystruct
void push(lua_State* l, T& value)

如果我删除我的 push() 的最一般形式函数,我的应用程序的其余代码,它调用 push()以类型作为参数正确解析为 push(lua_State * L, const boost::tuples::cons<HT, TT> & value)函数的版本。因此,出于某种原因,最通用的版本具有更高的优先级,这是我不想要的。

编辑: 我正在尝试遵循 Anycorn 的建议,但我不太擅长这个。我要离开 boost::tuples::cons版本不变,如果参数派生自 boost::tuples::cons,我想禁用通用版本:

template<typename T, typename HT, typename TT>
void push(lua_State* l, T& value, typename boost::disable_if<boost::is_base_of< boost::tuples::cons<HT, TT>, T>, T>::type* =0 ){
    Luaproxy<T>::new_c(l, value, false);
}

它仍在考虑 push(l, boost::make_tuple(mystruct)) 的缺点类型

[cut] /home/pisto/sorgenti/hopmodv4/src/hopmod/lua/push_function.hpp:48:6: note: template void lua::push(lua_State*, lua::Luaproxy&) /home/pisto/sorgenti/hopmodv4/src/hopmod/lua/push_function.hpp:51:6: note: template void lua::push(lua_State*, const T&, typename boost::disable_if, T>, T>::type*) /home/pisto/sorgenti/hopmodv4/src/hopmod/lua/push_function.hpp:56:6: note: template void lua::push(lua_State*, const boost::tuples::cons&)

最佳答案

这个

template<> template<typename HT, typename TT>
void push< boost::tuples::cons<HT, TT> >(lua_State * L, const boost::tuples::cons<HT, TT> & value){
    push(L, value.get_head());
    push(L, value.get_tail());
}

应该是

template<typename HT, typename TT>
void (lua_State * L, const boost::tuple<HT, TT> & value){
    push(L, value.get_head());
    push(L, value.get_tail());
}

注意 make_tuple 返回元组,而不是缺点。

如果我正确理解你的问题

更新:

tuple 继承自 cons。如果参数不是 cons 的派生物,您必须做的是使通用模板失败,否则启用它。

http://www.boost.org/doc/libs/1_48_0/libs/utility/enable_if.html

http://www.boost.org/doc/libs/1_36_0/libs/type_traits/doc/html/boost_typetraits/reference/is_base_of.html

或者,您可以专门化元组模板函数并将元组转换为其基数,cons

更新:

看到您尝试做什么,您需要一种方法来测试元组: 让我们试试这个:

template<class T>
is_tuple : boost::mpl::false_ {};

template<class T0, class T1, ...>
struct is_tuple<tuple<T0, T1, ..> > : boost::mpl::true_ {};

然后根据元组和函数编写禁用/启用函数来处理cons<H,T> .元组函数必须调用cons函数。

关于c++ - boost::tuple 和通用结构的不同模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8685428/

相关文章:

c++ - 处理模板中的 void 类型

c++ - 使用共享指针 vector boost lambda

c++ - QTimer::singleShot() 在给定对象的父类中查找指定的槽,而不是对象本身

c++ - 计算字符串 C++ 中字符数的标准函数

c++ - 使用boost Spirit解析带有二进制信封的文本文件

c++ - 使用 boost 查找目录空间详细信息

c++ - 关于 Boost Statechart 中状态变化的通知

c++ - 是否应该将 GUI 应用程序警告消息发送到 std::cerr?

c++ - 如果模板构造函数参数是从非模板基类(Armadillo)派生的,它们似乎并不关心它们的类型。

c++ - 非模板类中模板方法中的dll和静态变量