Re: how to make a simple generic function... parameterized by
collection & value
Hi Daniel,
Is what I'm trying to do very much against the grain of C++11? Or is
it that I'm taking the wrong approach?
Scenario: I have validator functions that take a string and return an
object of a given type, e.g., int validator(string); string
validator(string); bool validator(string) --- or throws if the string
can't be converted to the required type (e.g., for int the string
doesn't represent a number or is too big or too small). These work
fine. But I also want to create a validator that takes an existing
validator plus a collection of specific values and returns a new
validator that does the conversion (or throws) and if it hasn't thrown
then checks to see if the converted item is in the collection.
I changed the code along the lines you suggested:
template<typename T>
struct identity { typedef T type; };
template<typename T>
using NonDeduced = typename identity<T>::type;
template<typename T>
using Validator = std::function<T(const std::string)>;
template<typename C>
Validator<typename C::value_type>
makeSetValidator(const C &validItems,
NonDeduced<Validator<typename C::value_type>>
validate)
{
return [=](const std::string s)->typename C::value_type{
const auto x = validate(s);
if (std::find(std::begin(validItems), std::end(validItems), x)
!= std::end(validItems))
return x;
throw ValueError("Invalid item '" + s + "'");
};
}
I also tried changing the call site:
auto v = makeSetValidator(std::set<int>{-4, 8, 31}, validate);
But g++ 4.7.0 gave me this:
main.cpp: In function ?void test9(const string&)?:
main.cpp:318:49: error: cannot resolve overloaded function ?validate?
based on conversion to type
?OptArg::NonDeduced<std::function<int(std::basic_string<char>)> > {aka
std::function<int(std::basic_string<char>)>}?
main.cpp: In function ?void test10(const string&)?:
main.cpp:356:42: error: no matching function for call to
?makeSetValidator(std::set<std::basic_string<char> >, <unresolved
overloaded function type>)?
main.cpp:356:42: note: candidate is:
In file included from optarg_option.hpp:17:0,
from optarg.hpp:33,
from main.cpp:14:
optarg_validator.hpp:104:1: note: template<class C>
OptArg::Validator<typename C::value_type>
OptArg::makeSetValidator(const C&,
OptArg::NonDeduced<std::function<typename
C::value_type(std::basic_string<char>)> >)
optarg_validator.hpp:104:1: note: template argument deduction/
substitution failed:
main.cpp:356:42: note: cannot convert
?std::set<std::basic_string<char>
(std::initializer_list<std::basic_string<char> >{((const
std::basic_string<char>*)(& const std::basic_string<char> [2]
{std::basic_string<char>(((const char*)"a"), (*(const
std::allocator<char>*)(& std::allocator<char>()))),
std::basic_string<char>(((const char*)"bee"), (*(const
std::allocator<char>*)(& std::allocator<char>())))})), 2u}, (*(const
std::less<std::basic_string<char> >*)(&
std::less<std::basic_string<char> >())), (*(const allocator_type*)(&
std::allocator<std::basic_string<char> >())))? (type
?std::set<std::basic_string<char> >?) to type ?const
std::basic_string<char>&?
Thanks!
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]