2

I have this code example:

#include <iostream>
#include <memory>

template <typename T>
void func1(T& value)
{
    std::cout << "passed 1 ..." << std::endl;
}

template <template <typename> class T, typename U>
void func2(T<U>& value)
{
    std::cout << "passed 2 ..." << std::endl;
}

int main()
{
    std::auto_ptr<int> a;
    const std::auto_ptr<int> ca;

    // case 1: using func1
    func1(a);  // OK
    func1(ca); // OK

    // case 2: using func2
    func2(a);  // OK
    func2(ca); // Compilation error

    return 0;
}

In the first case the function 'func1' accepts a generic argument regardless of the qualifier, however the second case the function 'func2' fails when the argument has the const qualifier. Why this happens ?

This is the compilation error:

make all 
Building file: ../src/Test2.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Test2.d" -MT"src/Test2.d" -o "src/Test2.o" "../src/Test2.cpp"
../src/Test2.cpp: In function ‘int main()’:
../src/Test2.cpp:27: error: invalid initialization of reference of type ‘std::auto_ptr<int>&’ from expression of type ‘const std::auto_ptr<int>’
../src/Test2.cpp:11: error: in passing argument 1 of ‘void func2(T<U>&) [with T = std::auto_ptr, U = int]’
make: *** [src/Test2.o] Error 1
hammer
  • 23
  • 5

1 Answers1

1

The problem is that in the case of func1, the compiler needs to deduce T and we get

  • T is std::auto_ptr<int> in the first call
  • T is const std::auto_ptr<int> in the second call

In both cases T is valid in itself.

Now for func2, the compiler needs to deduce T and U, where T is a template template parameter. What would be needed is:

  • T is std::auto_ptr, U is int in the first call
  • T is const std::auto_ptr, U is int in the second call

and there's your problem: T can not be const std::auto_ptr itself, as it combined a type-property const with a template std::auto_ptr which is not a valid type.

Daniel Frey
  • 55,810
  • 13
  • 122
  • 180
  • Hi, I understand what you say. But in both functions the compiler needs to deduct "T", in "func1" apparently can be deducted as "const std::auto_ptr" without problems, however you say that in "func2" is not valid. Really the point I want to know is whether this problem is specific to template template arguments in the process of deduction. Thanks – hammer Sep 27 '13 at 20:06
  • @hammer You don't really understand what it means. `func1` does *not* deduce `T` to `const std::auto_ptr`, but to `const std::auto_ptr` which is the crucial difference here. You need to distinguish between the template `std::auto_ptr` (which can not by itself be combined with `const`) and the type `std::auto_ptr` which is based on the template and which can be combined with `const`. – Daniel Frey Sep 27 '13 at 20:10
  • Now I see it all, that was the explanation I needed. Thanks for everything. – hammer Sep 27 '13 at 20:32