Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7956 Discussions

Template expansion during function overload resolution?

jlperla
Beginner
605 Views
I have an overloaded function with return type deduces from template arguments. But it tries to expand templates in the return type even though the overload is not matched.
The following code fails to compile on 11.1, windows (and VC2010). But compiles fine in g++.
[cpp]struct tag1{}; 
struct tag2{}; 
struct data1{ 
        typedef double value; 
}; 

struct data2{ //Doesn't have a ::value member 
}; 

template 
struct my_meta1 
{ 
        typedef typename T::value value; 
}; 

template 
struct my_meta2 
{ 
        typedef double value; 
}; 

//Matching the function based on the tag type 
template 
typename my_meta1::value 
f(tag1, DataType data) 
{ 
        return 0.0; 
} 

template 
typename my_meta2::value 
f(tag2, DataType data) 
{ 
        return 0.0; 
} 

int main() 
{ 
        f(tag1(), data1()); //Should match the tag1 specialization, which in turn gets the metadata from the data1() struct 
        f(tag2(), data2()); //Should match the tag2 specialization, which doesn't need to call anything on data2()\ 
		return 0;
} 
[/cpp]

Is failure this correct behavior? Any workarounds so that I can have the template argument dependent return types?
Thanks,
Jesse
0 Kudos
6 Replies
Feilong_H_Intel
Employee
605 Views
Hi Jesse,

I entered this test case to our problem-tracking database and let engineering team to take a look. They will see whether icc should report an error against this test case or not.

Thanks,
Feilong
0 Kudos
IDZ_A_Intel
Employee
605 Views
It looks like newer versions of g++ (g++ 4.1 and later) accept this code, they seem to do template argument deduction on the arguments first and don't bother instantiating the return type if there's no possible match forthearguments.We'll work on imitating this behavior in our gnu_version >= 410 compatibility modes.

thanks for reporting it.
0 Kudos
Feilong_H_Intel
Employee
605 Views
Jesse,

Engineering team has implemented a fix for this issue in the next major version of the compiler. I'll let you know when it is available for download.

Thanks,
Feilong
0 Kudos
jlperla
Beginner
605 Views
Thanks.
If it happens to sneak into a minor bug version release, that would be great as well. The amount of template metaprogramming to get around this is horrendous.
Also, hopefully the gcc compatibility mode works on the Windows version of the compiler, and I hope it doesn't turn off any other features. From what I can figure out, this behavior is the correct one and certainly comes up a lot in metaprogramming with SFINAE.
I put a link to this in the Visual Studio 2010 bug reports as well if you are interested in tracking those:
Thanks,
Jesse
0 Kudos
Judith_W_Intel
Employee
605 Views

This is a description of the fix we made. This does not fall under SFINAE because the argument mismatch is not a result of substitution.

Templates rejected on non-dependent parameters before deduction

In overload resolution, function templates are now rejected before deduction
is done if it can be shown that any of the non-dependent parameters cannot
match. If all those parameters are okay, deduction is then done and the
remaining parameters are checked. This can speed up overload resolution,
and in some cases avoids errors caused by instantiations needed to develop
the function type. For example:

template struct Z {
typedef T::x xx;
};
template Z::xx f(void *, T);
template void f(int, T);
struct A {} a;
int main() {
f(1, a); // Okay now. Formerly provoked an error on the instantiation
// of the Z in the return type, with T=A. Now the first f
// is ruled out on the basis of the first parameter without
// doing deduction and producing the routine type.
}

The C++ standard does not mandate a particular behavior here; it allows
but does not require such instantiations. However, test cases like the
above are accepted by recent versions of g++, and it seems reasonable to
do so.

0 Kudos
Feilong_H_Intel
Employee
605 Views

The latest intel compiler (Intel C++ Compiler XE 12.0 Update 2) contains the fix for this issue. You may download it at https://registrationcenter.intel.com.

Thanks,

Feilong

0 Kudos
Reply