0

I was reading the sample code on another post Specializations only for C++ template function with enum non-type template parameter

and I'm trying to take it one step further, by using a overloaded conversion operator to use the object as if it was its enum member to call a template function.

//in my .h
enum class AllowedTypes { Cat, Dog };

class A {
AllowedTypes animal;

public:
//constructor
A(AllowedTypes t): animal(t) {};
explicit operator AllowedTypes*() const { return (AllowedTypes*) animal; }
operator AllowedTypes() const { return animal; }
template <AllowedTypes type>
void ability() const;
}

//second class
struct B{
//tempalte function
template <AllowedTypes type>
void ability() const;
}

//in my cpp
template<>
void B::ability<AllowedTypes::Dog>() const
{
std::cout << "Dog ability." << std::endl;
}
template<>
void B::ability<AllowedTypes::Cat>() const
{
std::cout << "Cat ability." << std::endl;
}


//in my main
Class* a = new A(AllowedType(1))
Class* b = new B();

//this calls work!
b->ability<AllowedTypes::Cat>(); 

//trying to get the type and calling ability via conversion doesn't
AllowedTypes type = (AllowedTypes)*a; // this converts correctly!
b->ability<type>(); //does not call correctly

this last line doesn't work, I'm trying to put my converted object in the template and call the ability specific to the type that A has. I've tried a few different things but can't seem to find what I'm looking for, is there a proper way to do this?

cicero866
  • 75
  • 5

1 Answers1

2

The problem in your code is that you are trying to set a template type parameter using a runtime value rather than compile time value.

Class* a = new A(AllowedType(1)) // The call to new here makes 'type' below a runtime value

b->ability<AllowedTypes::Cat>(); // AllowedTypes::Cat can be supplied at compile time

AllowedTypes type = (AllowedTypes)*a; // this converts correctly!
b->ability<type>(); //does not call correctly

Here is your code running online which points to the exact problem. Next time your confused about why your template type isnt getting deduced correctly/throwing an error use constexpr to figure out why.

And here is an answer explaining why new results in an ill-formed constexpr: C++14: can you call new in a constexpr?

tangy
  • 3,056
  • 2
  • 25
  • 42