Pages

09 August, 2024

C++ Templates - Guarantee A Type Definition Has a Particular Constructor Signature?

#include
#include
#include

struct AppleMakeInfo {};

template class Apple {
static_assert(std::is_base_of::value, "T must be derived from AppleMakeInfo");

public:
std::function deleteFunc;

~Apple() { deleteFunc(); }

Apple(T* aMI) {};
};

template class AppleManager
{
static_assert(std::is_base_of::value, "T must be derived from AppleMakeInfo");
static_assert(std::is_base_of::value, "U must be derived from Apple");

public:

static U* MakeApple(T* aMI, std::function dF)
{
U* ret = new U(aMI);
ret->deleteFunc = dF;
All.push_back(ret);
return ret;
}

private:
AppleManager() {};

static std::vector All;
};

struct GrannySmithMakeInfo :public AppleMakeInfo {};

class GrannySmith :public Apple {};

class GrannySmithManager :public AppleManager {};



The above code block mostly compiles, however I am having trouble with one line causing a compile error:


U* ret = new U(aMI)


This line, during compilation, will show the following error in my IDE (compile error C2665):


'GrannySmith::GrannySmith': no overloaded function could convert all the argument types


To me, this reads like the typename U of the AppleManager template class does not have a constructor with a signature that matches new U(aMI) because nothing in my source indicates a guarantee/contract between AppleManager and whatever Type is provided for typename U for a constructor with the new U(aMI) signature to exist in the definition of the typename U Type. I'd use the where keyword in C# to get this kind of contract, but the closest there is for this in C++ is static_assert() which isn't actually a contract (AFAIK) but just acts the way a contract would at compile.


Assuming I'm understanding correctly and the code won't compile because there's no compiler guarantee that the type provided for typename U will have a constructor with a signature matching new U(aMI), what am I to do to provide this kind of guarantee to the compiler?


Many thanks for any help I get! I'm not so experienced with C++ so apologies if the code block above is embarrassingly amateur.

No comments:

Post a Comment

Thanks