I need to define a member function __say_hi
on a class template, which will not be called anywhere, but still need to be kept by my clang-based frontend. To do so, I add a constexpr static member which holds the address of the function.
The problem is that the __say_hi
might not compile if the template parameter (for example because T is not copy-able, but that might be for another reason). So I need to define the static member holding the address only if __say_hi
compiles fine.
For example:
template<typename T>
struct foo_t {
const char * __say_hi() const {
T copy(m_t); // <-- needs a copy constructor for T.
return "hi";
} // <-- this function won't be called anywhere, but must not be removed from the AST.
static constexpr auto __ODR_use = &foo_t::__say_hi; // <-- this ODR-uses the function, thus it will not be removed from the AST.
T m_t;
};
struct non_copyable_t {
non_copyable_t(non_copyable_t const &) = delete;
};
int main() {
foo_t<int> f1; // OK, int is copyable.
// foo_t<non_copyable_t> f2; // KO, T needs to be copyable.
}
How can I ODR-use __say_hi
only if it compiles (C++11 only)?
I tried using SFINAE to check for the member existence, but solution such as this one fails as the template is always true, even if said function doesn't compile.
Edit foo_t is part of library, so I can't know all the types it will be instantiated with, and therefore I can't write specialization for those.
It seems like this is not possible. To quote @user17732522, "there is nothing in the language to test the validity of an instantiation."