|
|
|
|
|
by pjmlp
429 days ago
|
|
C++ was designed as "Typescript for C" for its time, because sometimes that is exactly the kind of code one needs to write, even if we discourage many of the classical patterns when better alternatives exist. The same C example compiled in C++23 mode, https://godbolt.org/z/MWa7qqrK7 As for possible alternatives, here is a basic one without taking into consideration virtual mechanics, only to show the principles. #include <concepts>
template <class T>
concept has_mmap = requires (T obj)
{
{ obj.mmap() } -> std::convertible_to<int>;
};
class VFS {
public:
VFS() = default;
virtual ~VFS() = default;
};
class ExampleFS : public VFS {
// mmap not available
};
class ExampleWithMMAP : public VFS {
public:
int mmap() {
return 0;
}
};
int main() {
ExampleFS fs;
ExampleWithMMAP fsWithMMAP;
/*
<source>: In function 'int main()':
<source>:33:19: error: 'class ExampleFS' has no member named 'mmap'
40 | return fs.mmap();
|
*/
if constexpr (has_mmap<ExampleFS>) {
return fs.mmap();
}
// ExampleWithMMAP has mmap(), just call it without issues
if constexpr (has_mmap<ExampleWithMMAP>) {
return fsWithMMAP.mmap();
}
// want to use the variable name instead of the type?
if constexpr (has_mmap<decltype(fsWithMMAP)>) {
return fsWithMMAP.mmap();
}
}
-- https://godbolt.org/z/cjcbrzT3zNaturally it is possible to be a bit even more creative, and moreso with C++26 reflection. |
|