I am trying to use default raw pointer as a default template parameter. I read that non type template parameters are restricted to integral types, enums, pointers and references. With references I had no issues, but when I tried to use pointer I am facing such error:
error: non-type template argument of type 'Engine *' is not a constant expression.
Here is my code:
#include <iostream>
#include <memory>
using std::cout;
using std::endl;
class Engine
{
public:
void startEngine()
{
m_started = true;
cout << "Engine started!" << endl;
}
private:
bool m_started = false;
};
template<typename T, T* DEFAULT>
class Car
{
public:
explicit Car(const uint64_t uid) : m_uid(uid), engine(DEFAULT)
{
engine->startEngine();
}
private:
uint64_t m_uid;
T* engine;
};
namespace
{
std::shared_ptr<Engine> engine = std::make_shared<Engine>();
Engine* e = engine.get();
}
int main()
{
Car<Engine, e> lambo(0);
return 0;
}
The only restriction as I see now is that second template argument needs to have static storage duration and external or internal linkage but the code fits these requirements. Appreciate any help.
non-type template arguments must be a constant expression:
A template-argument for a non-type template-parameter shall be a converted constant expression (5.20) of the type of the template-parameter.
Perhaps you can workaround this making the object you point has static storage duration and linkage (see):
For pointers to objects, the template arguments have to designate the address of a complete object with static storage duration and a linkage (either internal or external), or a constant expression that evaluates to the appropriate null pointer or std::nullptr_t value.
Example:
namespace{
Engine e;
}
int main(){
Car<Engine, &e> lambo(0);
return 0;
}
As with any non-type template parameter, a pointer template parameter has to be known at compile time, or, in C++ Standard parlance, be a constant expression. And your pointer is not - compiler has no way of knowing what this address going to be when the program is executed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With