3

Can any one explain me the below

a few constructs are not deduced contexts

Qualified type names. A type name like Q<T>::X will never be used to deduce a template parameter T , for example.

Nontype expressions that are not just a nontype parameter. A type name like S<I+1> will never be used to deduce I , for example. Neither will T be deduced by matching against a parameter of type int(&)[sizeof(S<T>)] .

These limitations should come as no surprise because the deduction would, in general, not be unique (or even finite).

Why the T in Q<T>::X can't be deduced ? and why int(&)[sizeof(S<T>)] called as a Nontype expression, even it has the type parameter in it.

contents were taken from :"C++ Templates The Complete Guide"

EX(from book)

template <int N>
class X {
public:
   typedef int I;
   void f(int) {}
};

template<int N>
void fppm(void (X<N>::*p)(X<N>::I));

int main()
{
   fppm(&X<33>::f); // fine: N deduced to be 33
}

In the function template fppm() , the subconstruct X<N>::I is a nondeduced context.

Edit

I've read some answers which trigger me an another other question

template<typename T> void(T p1,typename foo<T>::subtype P2)

in the above deceleration if foo<T> is not deduced which subtype the compiler will choose for p2?

EDIT2

i am trying to below

#include <iostream>
#include <cstring>
template <typename T>
struct foo{
    using type=int;
    void print(type a){
        std::cout<<a<<"\n";
    }
};
template<>
struct foo<float>{
    using type=float;
    void print(type a){
            std::cout<<a<<"\n";
        }
};

template<typename T2>
void test(foo<T2> o,typename foo<T2>::type p){
    o.print(p);
}

 int main(){
     foo<float> o;
     test(o,1.2);
 }

It's silly but I wonder what is the type of the T2 after test(o,1.2)

RaGa__M
  • 2,550
  • 1
  • 23
  • 44
  • I don't get it, can you give us an example? – amchacon Oct 11 '16 at 14:40
  • Possible duplicate of [What is a nondeduced context?](http://stackoverflow.com/questions/25245453/what-is-a-nondeduced-context) – Michael Foukarakis Oct 11 '16 at 14:54
  • In your EDIT2 example, `T2` is deduced from the `o` argument, but is not deduced from the `p` argument. So deduction succeeds, and then `T2=float` is substituted in everywhere, and `typename foo::type` is evaluated to get `float`. – aschepler Oct 11 '16 at 18:18
  • @aschepler if it is deduced from the `o` arg then `T2` should be `foo` not just `float` isn't it? – RaGa__M Oct 11 '16 at 18:21
  • No, the compiler compares parameter type `foo` with argument type `foo` and figures out that in order to make them equal, `T2` must be `float`. – aschepler Oct 11 '16 at 18:23
  • @aschepler is that any terminology name for this comparison and matching that done by the compiler besides than saying it generally as a template deduction. – RaGa__M Oct 11 '16 at 18:32
  • It's called template argument deduction, and is covered in section 14.8.2 of the Standard. – aschepler Oct 11 '16 at 18:38
  • @aschepler thanks i've missed the "argument". – RaGa__M Oct 11 '16 at 18:40

1 Answers1

3

Consider the following example:

template <typename T>
struct C
{
    using type = T;
};

template <>    // specialization
struct C<float>
{
    using type = int;   // oops
};

template <>    // another specialization
struct C<char>
{
    char type;   // type is not even a type now
};


template <typename T>
void foo( typename C<T>::type x ) {}

template <typename T>
void foo( C<T>, typename C<T>::type x ) {}

int main()
{
    // foo(3);   // there are two parameter T (int & float)
                 // that both would deduce to int for type.
                 // Which T should the compiler chose?
    foo<int>(3);   // explicitly naming the type works.
    foo<float>(3);

    foo( C<int>{}, 3);          // works
    foo( C<float>{}, 3);        // works
    // foo( C<char*>{}, 3);     // doesn't work, conflicting types
    foo( C<char*>{}, "hello");  // works
}

This examples should make clear why this construct is not possible. Its easy to construct ambiguities which are impossible to resolve for the compiler.

André Bergner
  • 1,429
  • 10
  • 10