To be consistent with other classes in a library, my array class below has two read() methods. The first reads the entire array to an output iterator and returns an error code, the second reads a single value and returns that (using exceptions for errors).
The problem I have is that if I call the second read(size_t idx) method with an int, the compiler prefers the templated method. I need to explicitly specify an unsigned int to make it work. My question is, what are my options around this problem:
- Rename either read function to avoid overloading
- Use something like boost::enable_if to prevent the iterator version from working with non-iterators. This sullies the interface though...
- Any other ideas that I'm missing?
-------------------------------------------------------------
#include <iostream>
#include <iterator>
#include <vector>
struct FooArray
{
template <typename TIter>
int read( TIter out )
{
*out++ = 123.456; // copy stuff to output iterator
return 99; // error code
}开发者_Go百科
double read( size_t index )
{
return 1.234; // return value at index
}
};
int main(int argc, char**argv)
{
FooArray tmp;
std::cout << tmp.read(10u) << std::endl;
/* std::cout << tmp.read(10) << std::endl; COMPILER ERROR */
tmp.read( std::ostream_iterator<double>(std::cout,"\n") );
}
Furthermore, I don't think size_t
is guaranteed to be a synonym for unsigned
, so even with the "u" suffix the code might not be portable.
std::string
has a similar problem that it has to distinguish between:
string s(10, 97); //size_t, char
string t(s.begin(), s.end()); //iter
That would internally forward the call to a suitable helper function (needs a compiler-time test somewhere if the arguments are integral).
However, in your case, the return types are different as well, therefore you'll have to select the correct overload to begin with.
It won't look that bad with enable_if
:
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_integral.hpp>
struct FooArray
{
template <typename TIter>
typename boost::disable_if<boost::is_integral<TIter>, int>::type
read( TIter out )
{
*out++ = 123.456; // copy stuff to output iterator
return 99; // error code
}
double read( size_t index )
{
return 1.234; // return value at index
}
};
精彩评论