I'm experiencing an error on MSVC 19.43, while gcc and clang doesn't.
Here the code that I was testing on.
https://godbolt.org/z/nhWMPW1q4
#include
#include
template
struct deleter {
constexpr void operator()(T* ptr) {
delete ptr;
}
};
struct foo {
std::string str;
constexpr foo() = default;
constexpr foo(std::string const& s) : str(s) {}
constexpr foo(std::string&& s) : str(std::move(s)) {}
};
struct bar {
foo* ptr;
constexpr bar() : ptr(nullptr) {}
constexpr bar(foo* p) : ptr(p) {}
constexpr ~bar() { deleter{}(ptr); }
};
constexpr int func() {
bar(new foo());
return 5;
}
int main() {
static_assert(func() == 5);
}
According to cppreference, the implicitly defined destroyer is constexpr if it meets the requirements.
https://en.cppreference.com/w/cpp/language/destructor#Implicitly-defined_destructor
https://en.cppreference.com/w/cpp/language/constexpr#constexpr_destructor
On top of the requirements of constexpr functions, a destructor also needs to satisfy all following conditions to be constexpr-suitable:
For every subobject of class type or (possibly multi-dimensional) array thereof, that class type has a constexpr destructor.(until C++23)
The class does not have any virtual base class.
Now that std::string is constexpr, I thought that the implicitly defined destructor of foo should have a constexpr destructor. However, the MSVC compiler is saying that the destructor of foo is not marked as constexpr.
And when I added another bar that uses delete on destructor, MSVC suddenly becomes happy with the code.
https://godbolt.org/z/7Mz8G8rro
Is this a bug in MSVC or am I missing something from the standard?