I have a debug class that I use in my code to print various things. In this class I overload operator() to facilitate output. I have several operator()s to print vectors. When I added a template version, I came accross compile errors.
Here is the code:
template<class Type1>
inline debug&
operator()(const std::string& name,
typename std::vector<Type1>::const_iterator begin,
typename std::vector<Type1>::const_iterator end)
{
_stream << indent(internal) << "< " << name << " : [ ";
std::copy(begin, end, std::ostream_iterator<Type1>(_stream, " "));
_stream << "] >" << std::endl;
return *this;
}
And another vector print function I have:
inline debug&
operator()(const std::string& name,
typename std::vector<uint32_t>::const_iterator begin,
typename std::vector<uint32_t>::const_iterator end)
{
_stream << indent(internal) << "< " << name << " : [ " << std::hex;
std::copy(begin, end, std::ostream_iterator<uint32_t>(_stream, " "));
_stream << "] >" << std::endl;
return *this;
}
Where indent() does exactly what it says.
Here is the compile error:
../include/debug.hh:146:3: note: template<class Type1> relix::debug& relix::debug::operator()(const string&, typename std::vector<_RealType>::const_iterator, typename std::vector<_RealType>::const_iterator)
../include/debug.hh:146:3: note: template argument deduction/substitution failed:
assembler.cc:78:64: note: couldn't deduce template parameter ‘Type1’
Here is assembler.cc:78:
log(D_C(tl._tokens), tl._tokens.begin(), tl._tokens.end());
Where D_C() is a substitution preprocessor macro to extract the variable name and _tokens is a std::vector of token, where token has an overloaded operator<<().
The problem is with just the template:
The problem here is that
Type1cannot be deduced by the compiler. Consider what would be needed to actually deduce the type: The compiler would have to instantiatestd::vectorwith all possible types, including any potential instantiation ofstd::vectorto determine whether the argument to the function is a match.The simplest workaround is to drop
vectorfrom the explicit requirements in the signature and convert it to:Now the type can be trivially deduced, whatever the argument to the function is.