October 22, 2024
Chicago 12, Melborne City, USA
templates

ODR-use a member function of a template class only if it is valid


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.



You need to sign in to view this answers

Leave feedback about this

  • Quality
  • Price
  • Service

PROS

+
Add Field

CONS

+
Add Field
Choose Image
Choose Video