Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

template constant type conversion operator not working under linux (gcc)

Consider the following program:

#include <iostream>

template<int s>
class Pack
{
public:
    Pack(){}
    char data[s];
    template<typename X> operator X&(){ return *reinterpret_cast<X*>(data); }
    template<typename X> operator X const&()const{ return *reinterpret_cast<const X*>(data); }
};

int main()
{
    const Pack<8> p;
    const double d(p);
    std::cout<<d<<std::endl;
}

It compiles fine under Windows. Under linux I get:

test.cc: In function ‘int main()’:
test.cc:17: error: passing ‘const Pack<8>’ as ‘this’ argument of ‘Pack<s>::operator X&() [with X = double, int s = 8]’ discards qualifiers

Why? Why is it not taking the const type conversion operator? How can I fix this and still have the convenient templated type conversion operator (in const and not const version). Thanks!

like image 637
Nathan Avatar asked Nov 23 '10 17:11

Nathan


1 Answers

According to the C++03 Standard, that code is ill-formed because template argument deduction will not be able to deduce X& or X const& against const double.

C++03 missed to state that the reference is stripped off from the return type of the conversion function prior to deduction, so you can never get a match in your case. For C++0x, this will be fixed and is included in the latest working paper, so it may compile with some compilers that include the fix retroactively.

Your code actually has a different problem: GCC does implement that defect report resolution, and therefor compares double (it strips off cv-qualifiers prior to deduction!) against X and against X const. Only X matches and so only that first conversion function is the single candidate in a call with a const Pack<8> argument - that's why GCC complains about the missing const on the conversion function. If you try the following code it would work

// can't strip cv-qualifiers off "double const&" - there are no top-level 
// cv qualifiers present here!
double const &d(p);
like image 196
Johannes Schaub - litb Avatar answered Sep 22 '22 13:09

Johannes Schaub - litb