The underlying problem in your situation seems to be that you'd like to specialize the function template parse
for the special case when the template argument is a std::tuple
. Unfortunately, this kind of specialization isn't possible with function templates.
However, it is possible with class templates.
So, as a first step, you could define parse
as a static function of a struct
, like this:
using std::istream;
using std::tuple;
using std::make_tuple;
struct A { A(const istream &) {} };
struct B { B(const istream &) {} };
template <typename... Args>
struct parser
{
/* Your original function, now inside a struct.
I'm using direct tuple construction and an
initializer list to circumvent the order-of-
construction problem mentioned in the comment
to your question. */
static tuple<Args...> parse(const istream &strm)
{ return tuple<Args...> {Args(strm)...}; }
};
template <typename... Args>
struct parser<tuple<Args...>>
{
/* Specialized for tuple. */
static tuple<Args...> parse(const istream &strm)
{ return parser<Args...>::parse(strm); }
};
You can then call it in the desired way:
int main()
{
typedef tuple<A,B> tuple_type;
auto tup = parser<tuple_type>::parse(std::cin);
return 0;
}
As a second step, you can define a function template (again) which passes the arguments on to the right specialization of the struct:
template <typename... Args>
auto parse(const istream &strm) -> decltype(parser<Args...>::parse(strm))
{ return parser<Args...>::parse(strm); }
And now you can use it in exactly the way you wanted:
int main()
{
typedef tuple<A,B> tuple_type;
auto tup = parse<tuple_type>(std::cin);
return 0;
}
(And you can still use it in the old way, too: auto tup = parse<A,B>(std::cin)
.)
Remark. As mentioned in the comment to parser::parse(), I used direct tuple construction instead of make_tuple
to avoid problems with the order of construction of the tuple elements. This is not directly related to your question, but a good thing to do. See how to avoid undefined execution order for the constructors when using std::make_tuple.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…