模板:数组大小的扣除失败

时间:2016-05-01 11:12:23

标签: c++ templates iterator

我正在尝试将要处理的元素类型限制为std::array<std::string,N>>,但N的模板替换失败。

main.cpp:10:1: note:   template argument deduction/substitution failed:
main.cpp:31:34: note:   couldn't deduce template parameter 'N'
     print(word.begin(),word.end());

我的尝试如下。

#include <iostream>
#include <string>
#include <vector>
#include <array>
#include <boost/range/iterator_range.hpp>    

template<typename ForwardIterator,std::size_t N>
typename std::enable_if<std::is_same<typename ForwardIterator::value_type,std::array<std::string,N> >::value >::type
print(ForwardIterator begin, ForwardIterator end)
{
    for( auto const & arr : boost::make_iterator_range(begin,end) )
    {
        for( auto const & item : arr)
        {
            std::cout<<item<<' ';
        }
        std::cout<<'\n';
    }
}

int main()
{
    std::vector<std::array<std::string,2>> word;
    word.push_back( {{"hello","Hi"}} );
    word.push_back( {{"b","bye"}} );
    print(word.begin(),word.end());
}

Demo on Coliru

2 个答案:

答案 0 :(得分:3)

你必须改变你的方法,而不是将类型与未知大小的数组进行比较(也就是说,编译器不能告诉你N你想到的是什么),验证是否类型本身可以推断为数组:

#include <array>
#include <iterator>
#include <type_traits>
#include <string>

template <typename T, typename A>
struct is_std_array : std::false_type {};

template <typename T, std::size_t N>
struct is_std_array<T, std::array<T,N>> : std::true_type {};

template<typename ForwardIterator>
auto print(ForwardIterator begin, ForwardIterator end)
    -> typename std::enable_if<
           is_std_array<std::string, typename std::iterator_traits<ForwardIterator>::value_type>::value
       >::type
{

}

此外,不是std::iterator_traits的使用。

DEMO

答案 1 :(得分:1)

(这不是一个完整的答案,只是试图直观地解释为什么当前的方法不起作用。)

这是因为你没有给它任何推断N的机会。 N在签名中只出现一次,即 test 是否相等。这并不会强制类型彼此相等。

作为一个非常简单的示例,您不会期望此代码会强制Tint

template<typename T>
typename std::enable_if<std::is_same<T,int >::type
void foo(T) {
}

(另外,foo的返回类型不是Tint,它将是一种特殊的布尔类型。再次,可能不是你的意思想。)

归根结底,你想要什么?我想你想确保只用值类型为std::array

的迭代器调用它