Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Candidate template ignored because template argument could not be inferred

Tags:

c++

templates

What is wrong with the following piece of code?

#include <iostream>  template<typename K> struct A {     struct X { K p; };     struct Y { K q; }; };  template<typename K> void foo(const typename A<K>::X& x, const typename A<K>::Y& y) {     std::cout << "A" << std::endl; }  int main() {     A<float>::X x;     A<float>::Y y;     foo(x, y);   } 

clang gives the following error message:

17:2: error: no matching function for call to 'foo'         foo(x, y);               ^~~ 10:6: note: candidate template ignored: couldn't infer template argument 'K' void foo(const typename A<K>::X& x, const typename A<K>::Y& y) {      ^ 1 error generated. 
like image 939
Danvil Avatar asked Sep 24 '12 13:09

Danvil


2 Answers

The argument K in const typename A<K>::X is not deducible. Basically, everything left of a :: is not deducible (if :: separates a nested-name).

It's trivial to see why it makes no sense to ask for deduction by running through this thought experiment:

struct A { typedef int type; } struct B { typedef int type; }  template <typename T> void foo(typename T::type);  foo(5);   // is T == A or T == B ?? 

There's no one-to-one mapping from types to nested types: Given any type (such as int), there could be many ambient types of which it is a nested type, or there needn't be any.

like image 197
Kerrek SB Avatar answered Oct 19 '22 11:10

Kerrek SB


template<typename K> void foo(const typename A<K>::X& x, const typename A<K>::Y& y) {     std::cout << "A" << std::endl; } 

K cannot been deduced, since it's in non-deduced context.

n3337 14.8.2.5/4

In certain contexts, however, the value does not participate in type deduction, but instead uses the values of template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.

n3337 14.8.2.5/5

The non-deduced contexts are:

— The nested-name-specifier of a type that was specified using a qualified-id.

like image 27
ForEveR Avatar answered Oct 19 '22 09:10

ForEveR