This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C6000 compiler 7.4.7 SFINAE constructors

Hello

I am trying to implement a class for which there is a templated constructor that behaves differently depending on the type of its argument. In particular, it should distinguish between regular function pointers and member function pointers. My idea was to use SFINAE and the fact that function pointers cannot be cast to member function pointers and vice versa. My test program looks like this:

#include <iostream>

struct A { int f() { return 0; } };

struct sf
{
  template<typename T> sf(T t, char (*dummy)[ sizeof(reinterpret_cast<void(*)()>(static_cast<T>(0))) ] = 0) { std::cout << "first\n"; }
  template<typename T> sf(T t, char (*dummy)[ sizeof(reinterpret_cast<void(sf::*)()>(static_cast<T>(0))) ] = 0) { std::cout << "second\n"; }
};

double z(int, int)
{
    return -1.0;
}

int main()
{
  sf tmp1(&A::f);
  sf tmp2(z);
}

This compiles and runs fine with GCC, printing:

second
first

Unfortunately, the TI compiler complains that

"C:/test.cpp", line 18: error #311: more than one instance of constructor "sf::sf" matches the argument list:
            function template "sf::sf(T, char (*)[4U])"
            function template "sf::sf(T, char (*)[8U])"
            argument types are: (int (A::*)())
"C:/test.cpp", line 19: error #311: more than one instance of constructor "sf::sf" matches the argument list:
            function template "sf::sf(T, char (*)[4U])"
            function template "sf::sf(T, char (*)[8U])"
            argument types are: (double (int, int))

Is this a bug?

Thanks in advance

Markus

  • Which version of GCC are you using, and what flags?  My copy of GCC rejects this code with an error.

  • Archaeologist said:

    Which version of GCC are you using, and what flags?  My copy of GCC rejects this code with an error.

    I just tested it again, gcc 4.8.3 compiles the code just fine, but I now see that 4.7.3 and 4.6.4 don't and moreover complain about the same ambiguity.

    The command line was "g++ -std=c++98 -pedantic".

    I have to say that I wouldn't be surprised to learn that the code is actually faulty, although my current understanding is that it should compile.

    Thanks again

    Markus

    EDIT: just tested gcc 4.9.0 online, the behavior is the same as with 4.8.3

    EDIT: online icc 13.0.1 also produces "second\nfirst\n"

    EDIT: I now realize that the casts probably aren't constant integer expressions that are required in this context. I'll rewrite the code to explicitly specialize for functions with up to 10 parameters or so. That should work in any case. Curiously compilers don't seem to agree on the issue, though.

  • After a little more reading, I believe that the code I posted is in fact valid and its rejection is therefore unjustified.

    The reason is that sizeof(expr) is an integer constant expression (of type size_t) for any expression expr and is thus allowed in array declarations. While this expression is not evaluated (which is a term that describes the execution of the program on the abstract machine), it must still be valid. Also, an invalid conversion is explicitly listed as one of the causes for argument deduction failure:

    Type deduction may fail for the following reasons: 
      [...] 
      - Attempting to perform an invalid conversion in either a template argument
        expression, or an expression used in the function declaration.

  • I apologize for the delay.  

    I discovered that if you upgrade to compiler version 8.0.0, your problem is not solved, but it does get better.

    % cl6x --abi=eabi --verbose_diagnostics file.cpp
    "file.cpp", line 18: error: no instance of constructor "sf::sf" matches the
              argument list
                argument types are: (int (A::*)())
        sf tmp1(&A::f);
                ^
    
    1 error detected in the compilation of "file.cpp".
    
    >> Compilation failure
    

    So, I filed SDSCM00051444 in the SDOWP system to have this addressed.  Feel free to follow it with the SDOWP link below in my signature.

    Thanks and regards,

    -George