1

A library that I'm porting from Visual Studio to Xcode uses a template chain. My chain works correctly in Visual Studio. However, when I compile it in Xcode using Apple LLVM 6.0, I get the error

References to overloaded function could not be resolved; did you mean to call it?

Update

I've created a standalone example that compiles in Visual Studio but fails to compile in Xcode with the same error that I'm seeing in my library.

Note: I can probably fix my library code by other means. However, I'd like to take this opportunity for someone to teach me something new about disambiguation and the differences between the compilers. Is this pattern non-standard? Did it only work in Visual Studio because of a language extension?

class Test1{};
class Test2{};
struct NullType{};

template< class T, int id>
class SpecialHandler
{
public:
    enum { ETypeId = id };
    void handlerFunc( float, int ){}
};

template<typename TReturn, class TObj, typename TParam1, typename TParam2>
class TestResolveClass
{
public:
    template< TReturn (TObj::*Func)(TParam1, TParam2 ) >
    inline static void funcThatFailsResolve(TObj* obj)
    {
        (void)obj;
        (void)Func;
    }
};

template< class TSpecialHandler, class TParent >
class Chain :
    public TParent
{
public:
    typedef TParent Parent;
    typedef TestResolveClass<void, SpecialHandler<Test1, 1>, float, int> TestResolver1;
    typedef TestResolveClass<void, SpecialHandler<Test2, 2>, float, int> TestResolver2;
    typedef TestResolveClass< void, TSpecialHandler, float, int > TemplatedTestResolver;


    void traverseChain()
    {
        Parent* parentPtr = static_cast<Parent*>( this );
        parentPtr->traverseChain(); // up the chain we go

        SpecialHandler<Test1, 1> testaroo;
        TestResolver1::funcThatFailsResolve< &SpecialHandler<Test1, 1>::handlerFunc >( &testaroo ); // no error

        TemplatedTestResolver::funcThatFailsResolve< //<-- Reference to overloaded function could not be resolved; did you mean to call it?
            &TSpecialHandler::handlerFunc
            >( &m_handler );
        TemplatedTestResolver::funcThatFailsResolve< // <-- Reference to overloaded function could not be resolved; did you mean to call it?
            static_cast<void (TSpecialHandler::*)( float, int )>( &TSpecialHandler::handlerFunc )
            >( &m_handler );
    }
private:
    TSpecialHandler m_handler;
};

template<>
class Chain< NullType, NullType >
{
public:
    void traverseChain(){}
};

typedef Chain< NullType, NullType > ChainLink0;
typedef Chain< SpecialHandler<Test1, 1>, ChainLink0 > ChainLink1;
typedef Chain< SpecialHandler<Test2, 2>, ChainLink1 > ChainLink2;
typedef ChainLink2 FullChain;

class ChainContainer :
    public FullChain
{
public:
    ChainContainer()
    {
        traverseChain();
    }
};

int main()
{
    ChainContainer test;
    (void)test;
}

Thanks for your help.

Update 2: I changed a few of the names to be more useful and restructured the code to be clear where the problem is. I also placed some example code before the error to show a situation in which the error does not appear.

sbsmith
  • 600
  • 1
  • 5
  • 16
  • 1
    Please reduce the problem to a small **complete** example. – Cheers and hth. - Alf Jan 17 '15 at 08:41
  • I'll see if I can reproduce the problem with an example that does not use the callback object. Thanks for taking a look. – sbsmith Jan 17 '15 at 16:54
  • I've posted a standalone example. Thanks again. – sbsmith Jan 18 '15 at 04:39
  • What are the compiler versions involved? I think you have two functions with the same signature in different base classes. I would have guessed that the first that is found during lookup wins, because in that particular baseclass itself there are no overloads. BTW: Can you reduce the amount of code by dropping the template stuff? – Ulrich Eckhardt Jan 18 '15 at 08:42
  • GCC 4.9.2 seems to consider the left bracket following the "...funcToResolve" to be a binary operator <. I also threw threw this at clang 3.5.0 and one thing that might help is that it underlines the part of the line that is "TestResolveClass< void, TFuncClass, float, int >().funcToResolve". What if you create an object first, then call the template memberfunction? Similarly, what if you use a typedef for the class? Also, what if you use `type::function()` instead to invoke the static function? – Ulrich Eckhardt Jan 18 '15 at 08:53
  • Thanks for the help, Ulrich. Xcode is set to Apple LLVM 6.0 and on Windows it compiles and (my library code) runs correctly in the test framework in Visual Studio 2012 and 2013. I'm not sure if I can drop the template stuff as I suspect the template stuff has something to do with the resolution problem. I will try your other suggestions and do a bit of research into type::function since that is new to me. – sbsmith Jan 18 '15 at 21:57
  • 1
    @UlrichEckhardt It looks like the templates are at the root of the problem. I rewrote the code above to show that a call using a manually completed template works. – sbsmith Jan 18 '15 at 23:00
  • 1
    At a first glance, it seems you're missing the `template` keyword: `TemplatedTestResolver` looks like a dependent name, hence it should be `TemplatedTestResolver::template funcThatFailsResolve` – dyp Jan 18 '15 at 23:06
  • 1
    Once we fix the issue with `template`, what remains is an error with the second invocation. IIRC this error is due to the restrictions on non-type template arguments of pointer type, see e.g. http://stackoverflow.com/q/15885399 – dyp Jan 18 '15 at 23:13
  • @dyp Thanks! I had a feeling it was going to be something small. The template keyword was what I was looking for. My code compiles and all my test cases pass now :) – sbsmith Jan 18 '15 at 23:40

0 Answers0