Google


   


You are here: CodeIdol.com > C++ > C++ Templates: The Complete Guide > Template Argument Deduction > Deduced Contexts

SAVE
Digg
Shown on del.icio.us del.icio.us
See Whos Talking About This on Technorati Technorati
I've Reddit reddit

11.2 Deduced Contexts

Parameterized types that are considerably more complex than T can be matched to a given argument

type. Here are a few examples that are still fairly basic:

template<typename T> 
void f1(T*); 

template<typename E, int N> 
void f2(E(&)[N]); 

template<typename T1, typename T2, typename T3> 
void f3(T1 (T2::*)(T3*)); 

class S { 
  public: 
    void f(double*); 
}; 

void g (int*** ppp) 
{ 
    bool b[42]; 
    f1(ppp);    // deduces T to be int** 
    f2(b);      // deduces E to be bool and N to be 42 
    f3(&S::f);  // deduces T1 = void, T2=S, and T3 = double 
} 

Complex type declarations are built from more elementary constructs (pointer, reference, array, and function declarators; pointer-to-member declarators; template-ids; and so forth), and the matching process proceeds from the top-level construct and recurses through the composing elements. It is fair to say that most type declaration constructs can be matched in this way, and these are called deduced contexts. However, 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), although qualified type names are sometimes easily overlooked. A nondeduced context does not automatically imply that the program is in error or even that the parameter being analyzed cannot participate in type deduction. To illustrate this, consider the following, more intricate example:

// details/fppm.cpp 

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. However, the member-class component X<N> of the pointer-to-member type is a deducible context, and when the parameter N, which is deduced from it, is plugged in the nondeduced context, a type compatible with that of the actual argument &X<33>::f is obtained. The deduction therefore succeeds on that argument-parameter pair.

Conversely, it is possible to deduce contradictions for a parameter type entirely built from deduced contexts. For example, assuming suitably declared class templates X and Y:

template<typename T> 
void f(X<Y<T>, Y<T> >); 

void g() 
{ 
    f(X<Y<int>, Y<int> >());   // OK 
    f(X<Y<int>, Y<char> >());  // ERROR: deduction fails 
} 

The problem with the second call to the function template f() is that the two arguments deduce different arguments for the parameter T, which is not valid. (In both cases, the function call argument is a temporary object obtained by calling the default constructor of the class template X.)

    SAVE
    Digg
    Shown on del.icio.us del.icio.us
    See Whos Talking About This on Technorati Technorati
    I've Reddit reddit

    You are here: CodeIdol.com > C++ > C++ Templates: The Complete Guide > Template Argument Deduction > Deduced Contexts


    ADBRITE ads links
       
    Related tags







    Popular Categories
    Unix books and guides

    AJAX popular information
    C# language guides
    Windows books and cookbooks

    .......








    Business Key Top Sites

    be number one
    rate your site





    © CodeIdol Labs, 2007 - 2009