Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two different results on GCC 4.6 and 4.7 for template template deduction

Considering the following code :

#include <iostream>
#include <vector>
#include <array>
#include <type_traits>

// Version A
template<typename T>
void f(const T& x)
{
    std::cout<<"Version A"<<std::endl;
}

// Version B
template<typename... T1, template<typename...> class T>
void f(const T<T1...>& x)
{
    std::cout<<"Version B"<<std::endl;
}

// Version C
template<typename T1 = double, typename TN = size_t, template<typename, TN...> class T, TN... N>
void f(const T<T1, N...>& x)
{
    std::cout<<"Version C"<<std::endl;
}

// Main
int main(int argc, char* argv[])
{
    f(double());
    f(std::vector<double>());
    f(std::array<double, 3>());
    return 0;
}

GCC 4.6.2 on Windows gives :

Version A
Version B
Version C

and GCC 4.7.1 on Linux gives :

Version A
Version B
Version A

So the question is : WHY ? Is this a bug or an undefined behaviour ? Should I post it on the GCC bug report ?

like image 461
Vincent Avatar asked Oct 06 '22 15:10

Vincent


1 Answers

It looks like a bug in gcc 4.7.x (4.7.2 has the same issue). Here's a simpler example:

template<int N> struct S {};
template<typename T = int, T N> void f(S<N>) {}
int main() { S<1> s; f(s); }

gcc 4.7.2 fails with:

source.cpp:3:25: error: no matching function for call to 'f(S<1>&)'
source.cpp:3:25: note: candidate is:
source.cpp:2:38: note: template<class T, T N> void f(S<N>)
source.cpp:2:38: note:   template argument deduction/substitution failed:
like image 118
ecatmur Avatar answered Oct 10 '22 04:10

ecatmur