0

The example here shows how we can use TMP to have the compiler elide functions based on whether a member exists for a given type. I want to write a metafunction that works for classes based on templates. Compilation should succeed if a class based on a template is provided in the function call that has the desired member.

The class:

template <typename KeyType>
struct RawBytesEntry
{
    bool used = false;
    size_t psl = 0;
    KeyType key;
    ...
}

I tried a whole slew of different suggestions and syntax permutations but I couldn't get it to work. Does anyone have any suggestions? Here is what I think is the "closest" I got:

template <template <typename> typename EntryType, typename = void>
struct has_psl : std::false_type
{
};

template <template <typename KeyType> typename EntryType>
struct has_psl<EntryType<KeyType>, std::void_t<decltype(EntryType<KeyType>::psl)>> : std::true_type
{
};

template <template <typename KeyType> typename EntryType, std::enable_if<has_psl<EntryType>::value>>
bool f(EntryType<KeyType> *buffer, size_t offset, EntryType<KeyType> *new_entry)
Arthur M
  • 447
  • 5
  • 21
  • None of your attempts makes sense to me. What are you trying to accomplish? – Captain Giraffe Jun 25 '22 at 04:04
  • class templates dont have member functions, classes do. Please include a complete example ([mcve]) – 463035818_is_not_an_ai Jun 25 '22 at 07:18
  • Does this answer your question? [Templated check for the existence of a class member function?](https://stackoverflow.com/questions/257288/templated-check-for-the-existence-of-a-class-member-function) – G. Sliepen Jun 25 '22 at 09:41
  • @463035818_is_not_a_number I made an edit to change references to "template class" to "class based on a template". My understanding was that these were interchangeable, and that both referred to a class based on a template, whose type is known at compile time and therefore we can make static assertions about it's members. It seems that may not be the case: https://stackoverflow.com/questions/879535/what-is-the-difference-between-a-template-class-and-a-class-template – Arthur M Jun 26 '22 at 19:08

1 Answers1

3

The template parameters of the template template parameter can not be used in the body.

template <typename T, typename = void>
struct has_psl : std::false_type
{};

template <template <typename> typename EntryType, typename KeyType>
struct has_psl<EntryType<KeyType>, std::void_t<decltype(EntryType<KeyType>::psl)>> : std::true_type
{};

template <template <typename> typename EntryType, typename KeyType, std::enable_if<has_psl<EntryType<KeyType>>::value>>
bool f(EntryType<KeyType> *buffer, size_t offset, EntryType<KeyType> *new_entry) {
    return true;
}

And then,

static_assert(has_psl<int>::value == false);
static_assert(has_psl<RawBytesEntry<int>>::value == true);

Online Demo

Nimrod
  • 2,908
  • 9
  • 20