Boost logo

Boost Users :

Subject: Re: [Boost-users] function template argument deduction with std::tuple
From: Ireneusz Szcześniak (irek.szczesniak_at_[hidden])
Date: 2017-11-16 08:33:09


Hi Gavin,

Thanks for your email. However, I wonder why the other
specializations are used, and not the one for type Label. If your
reasoning was correct, the code for other specializations (for Label1,
Label2, Label3) would fail to compile too.

My guess is that for some season a compiler does not consider the
specialization of get_cost for type Label, and reverts to the get_cost
declaration, thus complaining that the type for auto cannot be deduced
simply because there is no definition of the function. There might be
some interplay between function overloading and function template
specialization.

I can be very specific and specialize the function this way:

> template<>
> auto
> get_cost<>(const Label<graph> &l)
> {
> return std::get<0>(l);
> }

And the code compiles.

The example compiles also when I overload the function:

> auto
> get_cost(const Label<graph> &l)
> {
> return std::get<0>(l);
> }

But in that case I have to make sure the overload is defined before
any other template definition which uses this overload.

To illustrate what I mean, I'm attaching the same example as before,
but this time I added the template function callme, which uses
get_cost. Right after the callme template, there is the
specialization definition of get_cost(const Label<graph> &l) with
which the example compiles even though that specialization comes after
the callme template definition. If you comment out that
specialization of get_cost(const Label<graph> &l), and uncomment the
overload definition get_cost(const Label<graph> &l), the compilation
fails, because the overload should be defined before the callme
template definition (check it out, and move the overload of get_cost
before the callme template).

For that reason I would like to specialize the get_cost function
template, and not to overload the get_cost function. And when I
specialize the get_cost function, I don't want to be too specific and
provide the definition for a single type (i.e., Label<graph>):

> template<>
> auto
> get_cost(const Label<graph> &l)
> {
> return std::get<0>(l);
> }

But I want to be general, and provide a specialization template:

> template <typename Graph>
> auto
> get_cost(const Label<Graph> &l)
> {
> return std::get<0>(l);
> }

That specialization above maybe should look something like this,
because it's a template of a complete specialization, but it doesn't
compile:

> template <typename Graph>
> template <>
> auto
> get_cost(const Label<Graph> &l)
> {
> return std::get<0>(l);
> }

So I guess I could conclude with a question: How can I make sure that
a compiler considers the specialization for type Label?

Best,
Irek

On 16.11.2017 06:18, Gavin Lambert via Boost-users wrote:
> On 15/11/2017 20:55, Ireneusz Szcześniak wrote:
>> I have a problem related to function template argument deduction with
>> std::tuple (with boost::tuple too).  I attach a file with the complete
>> source you can compile. Below I describe the code.
>>
>> I have a template function declaration:
>>
>>  > template <typename T>
>>  > auto
>>  > get_cost(const T &);
> [...]
>> But I cannot use the templated function:
>>
>>  > get_cost(l);
>>
>> I get this error:
>>
>>  > error: use of 'auto get_cost(const T&) [with T =
>>  > std::tuple<unsigned int>]' before deduction of 'auto'
>
> The problem is that you are never actually implementing the general
> method, and thus the compiler can't infer what the return type should be.
>
> You are providing several "better" overloads, but this first overload
> still participates in overload resolution and the compiler doesn't
> like that it has an undetermined return type.
>
> The code compiles if you specify "void" as the return type for the
> above method instead (or indeed pretty much anything except "auto"),
> or give it an actual implementation before you try to call any of the
> overloads.
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> https://lists.boost.org/mailman/listinfo.cgi/boost-users




Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net