我正在尝试将要处理的元素类型限制为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());
}
答案 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
的使用。
答案 1 :(得分:1)
(这不是一个完整的答案,只是试图直观地解释为什么当前的方法不起作用。)
这是因为你没有给它任何推断N
的机会。 N
在签名中只出现一次,即 test 是否相等。这并不会强制类型彼此相等。
作为一个非常简单的示例,您不会期望此代码会强制T
为int
:
template<typename T>
typename std::enable_if<std::is_same<T,int >::type
void foo(T) {
}
(另外,foo
的返回类型不是T
或int
,它将是一种特殊的布尔类型。再次,可能不是你的意思想。)
归根结底,你想要什么?我想你想确保只用值类型为std::array