I have problem with the following code (minified example):
#include <stdint.h>
class Color {
public:
Color (uint32_t r=0, uint32_t g=0, uint32_t b=0)
:r(r), g(g), b(b) {}
~Color ()=default;
private:
uint8_t r;
uint8_t g;
uint8_t b;
};
template<const Color &color>
struct text_descriptor_clr {
int id;
uint32_t font;
const char *label;
};
class Text {
public:
template<const Color &use_color>
void create (const text_descriptor_clr<use_color> &d)
{
font=d.font;
}
uint32_t font;
};
extern const Color WHITE;
const Color WHITE(255,255,255);
int main()
{
Text t1;
text_descriptor_clr<WHITE> d;
t1.create(d);
}
It compiles with no error with gcc 4.8.2:
g++ --version
g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
...
g++ -o gcctest gcctest.cpp -std=c++0x -Wall -Wextra -pedantic
(no errors)
But fails, when compiled with gcc 5.2.0:
g++ --version
g++ (GCC) 5.2.0
...
g++ -o gcctest gcctest.cpp -std=c++0x
gcctest.cpp: In function ‘int main()’:
gcctest.cpp:38:13: error: no matching function for call to ‘Text::create(text_descriptor_clr<WHITE>&)’
t1.create(d);
^
gcctest.cpp:24:7: note: candidate: template<const Color& use_color> void Text::create(const text_descriptor_clr<use_color>&)
void create (const text_descriptor_clr<use_color> &d)
^
gcctest.cpp:24:7: note: template argument deduction/substitution failed:
gcctest.cpp:38:13: note: couldn't deduce template parameter ‘use_color’
t1.create(d);
The most suspicious part in this code is that I'm using template with class instance as parameter, I couldn't find information that it is allowed. Not a type, not an int, but instance of Color class. With gcc 4.8.2 it works as expected.
However, the real problem is template parameter deduction (if I remove the last line from the function, it compiles with gcc 5.2.0)
What is the reason for the different behavior? Which gcc is right here?