模板向导的难题

时间:2010-10-28 10:46:55

标签: c++ templates

我想做以下事情:

const int someInt;
const std::vector<int> someIntList;
const std::vector<std::vector<int>> someNestedIntList;

Marshall(someInt); // trivial case
Marshall(someIntList); // difficult case
Marshall(someNestedIntList); // difficult case

我尝试了以下内容:

template<std::vector<class Element>> 
void Marshall(const std::vector<Element>& toBeMarshalled)
{
    for (int i=0; i<toBeMarshalled.size(); ++i)
        Marshall<Element>(toBeMarshalled[i]);
}

遗憾的是,这不能编译,我找不到合适的语法。

请注意,必须只有一个模板参数,否则嵌套列表的编组将不起作用。

更新:感谢FredOverflow的回答,我找到了我要找的东西。我忘了标准库中的所有容器类都有 value_type typedef。这可以用作我的问题的解决方法:

template <class Container> 
void Marshall(const Container& toBeMarshalled)
{
    for (UINT32 i=0; i<toBeMarshalled.size(); ++i)
        Marshall<Container::value_type>(toBeMarshalled);
}

这是一个补丁,但我认为这已经足够了。

4 个答案:

答案 0 :(得分:7)

您的模板有两个问题:

  1. 模板声明错误。您只在此处列出模板参数,而不是函数参数类型。此外,>>被解析为移位运算符。
  2. std::vector有两个模板参数。虽然在您的日常工作中,您很少使用第二个,它仍然存在并且应该列出,或者如果有人试图将std::vector与不使用默认分配器的std::vector一起使用,则模板将失败。
  3. 这适用于所有template< typename T > void Marshall(const T& toBeMarshalled) { // ... } template< typename T, class A > void Marshall(const std::vector<T,A>& toBeMarshalled) { for (typename std::vector<T,A>::size_type i=0; i<toBeMarshalled.size(); ++i) Marshall(toBeMarshalled[i]); } 个实例:

    {{1}}

答案 1 :(得分:4)

模板声明错误。做:

template< class Element >
void marshall( std::vector< Element > const& v )

干杯&amp;第h。,

答案 2 :(得分:3)

我可以提议SFINAE并推广一些元编程吗?

#include <boost/type_traits.hpp>
#include <boost/utility/enable_if.hpp>

template <class T>
struct has_begin_end
{
    template <class U,
              typename U::const_iterator (U::*)() const,
              typename U::const_iterator (U::*)() const>
    struct sfinae { };

    template <class U>
    static char test(sfinae<U, &U::begin, &U::end>*);

    template <class>
    static long test(...);

    enum { value = (1 == sizeof test<T>(0)) };
    typedef boost::integral_constant<bool, value> type;
};

template <class Value>
typename boost::disable_if<has_begin_end<Value>, void>::type
Marshall(const Value& value)
{
    std::cout << value << ' ';
}

template <class Container>
typename boost::enable_if<has_begin_end<Container>, void>::type
Marshall(const Container& c)
{
    std::for_each(c.begin(), c.end(), Marshall<typename Container::value_type>);
}

int main()
{
    const int someInt = 42;
    const std::vector<int> someIntList {2, 3, 5, 7};
    const std::vector<std::vector<int>> someNestedIntList {{11, 13}, {17, 19}};

    Marshall(someInt);
    Marshall(someIntList);
    Marshall(someNestedIntList);
}

答案 3 :(得分:2)

您粘贴的代码在模板声明的末尾包含>>。 C ++编译器将其解释为不是两个闭合尖括号,而是作为单个右移运算符。

尝试template<std::vector<class Element> >,括号之间有空格。