Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static assert that method cannot be called from constructor or destructor

Suppose I have the following classes:

template <typename SELF>
class Base {
protected:
    template <int X>
    void foo();
};

class Child : public Base<Child> {
public:
    Child() {
        //I want this to throw a static assertion failure
        foo<10>();
    }
    ~Child() {
        //Should also static assert here
    }
};

Is there any way I make the compiler throw a compile-time assertion failure if the templated member method foo() is called within the constructor or destructor? In other words, I want to prevent, at compile time, the method from being called within the constructor or destructor.

Please don't ask why foo is a template; this is just a simplified example of a more complex project.

like image 569
Patrick Wright Avatar asked Sep 08 '25 08:09

Patrick Wright


1 Answers

This solution works only with C++20, only for destructor, and it is not compile time. I also not sure that it works everywhere. I don't recommend to use it in production code.

#include <iostream>
#include <source_location>
#include <cassert>

template <typename SELF>
class Base {
protected:
    template <int X>
    void foo(std::source_location location = std::source_location::current())
    {
        assert(std::string_view(location.function_name()).find("::~") == std::string::npos);

        std::cout << location.function_name() << '\n';
    }
};

class Child : public Base<Child> {
public:
    Child() {
        //I want this to throw a static assertion failure
        foo<10>();
    }
    ~Child() {
        //Should also static assert here
        foo<10>();
    }
};

int main() {
    Child child;
    return 0;
}
like image 118
Sandro Avatar answered Sep 10 '25 06:09

Sandro