1

I have following situation, there are two interfaces:

interface ILLShapeAttribute
{
  virtual void DefineAttribute(const char* pszAttributeName, VARIANT* pvAttributeData) = 0;
};

interface ILLShapeNotification
{
  virtual bool IsUsed(const RECT& rcBounds) = 0;
    virtual void DefineAttribute(const char* pszAttributeName, VARIANT* pvAttributeData) = 0;
}

And 2 functions:

INT LlShapeGetAttributeList(LPCWSTR pwszShapefileName, ILLShapeAttribute* pIAttrInfo);
INT LlShapeEnumShapes(LPCWSTR pwszShapefileName, ILLShapeNotification* pIInfo);

In those both functions I want to call the same function IterateRecords2 which should get the pointer to the function DefineAttribute, e.g. ILLShapeAttribute::DefineAttribute and ILLShapeNotification::DefineAttribute

I defined it this way:

void IterateRecords2(ifstream& file, void (*pDefineAttribute)(const char*, VARIANT*))
{
  pDefineAttribute(NULL, NULL); //will be called with real values
}

Until now the code compiles and everythig is fine. But then I try to call the IterateRecords2 like

IterateRecords2(file, pIAttrInfo->DefineAttribute);

or

IterateRecords2(file, pIInfo->DefineAttribute);

I get the compiler error:

error C3867: 'ILLShapeAttribute::DefineAttribute': function call missing argument list; use '&ILLShapeAttribute::DefineAttribute' to create a pointer to member

Please: I know, that ILLShapeNotification could inherit from ILLShapeAttribute and then pass *ILLShapeAttribute instead of function pointer but I want to understand how it works.

Question: how can I pass the pointer to DefineAttribute to IterateRecords2?

9
  • 1
    Since when does c++ has an interface? is it not still using abstact classes only? Commented Jun 20, 2013 at 9:42
  • @omerschleifer It's probably a Microsoft extension of some sort. Commented Jun 20, 2013 at 9:55
  • @Angew I suppose it is a macro , just wanted to make sure Commented Jun 20, 2013 at 9:57
  • @doctorlove this is not COM, not C++/CLI etc. It's just C++. Commented Jun 20, 2013 at 10:00
  • @omerschleifer don't know since then, but I was able to declare interfaces in C++ in Visual Studio 6.0, so probably pretty long. Commented Jun 20, 2013 at 10:00

1 Answer 1

2

Question: how can I pass the pointer to DefineAttribute to IterateRecords2?

You can't.

A pointer-to-member-function is not compatible with a pointer to function, and even if it was, you'd need an object to call it on, you can't just call a member function without an object.

Some options are:

1) Take a pointer-to-member-function and pass an object.

This would solve your compiler error, but to be able to pass different types of object that are not related by inheritance you would need IterateRecords2 to be a template:

template<typename T>
void IterateRecords2(ifstream& file, T* obj, void (T::*pDefineAttribute)(const char*, VARIANT*))
{
  obj->pDefineAttribute(NULL, NULL);
}

Now you can use it like this:

IterateRecords2(file, pIAttrInfo, &ILLShapeAttribute::DefineAttribute);

or:

IterateRecords2(file, pIInfo, &ILLShapeNotification::DefineAttribute);

2) Bind an object and its member function into a callable type, and pass that:

void IterateRecords2(ifstream& file, std::function<void(const char*, VARIANT*)> DefineAttribute)
{
  DefineAttribute(NULL, NULL);
}

Then call it like:

IterateRecords2(file, std::bind(&ILLShapeAttribute::DefineAttribute, pIAttrInfo));

If you can't use std::function and std::bind you can replace them with boost::function and boost::bind

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.