sfinae создает функциональное тело? - PullRequest
4 голосов
/ 18 июня 2010

Я хочу обнаружить существование определенной функции-члена для класса, используя обычный трюк SFINAE.

template<typename T>
struct has_alloc
{
    template<typename U,U x>
    struct dummy;

    template<typename U>
    static char test(dummy<void* (U::*)(std::size_t),&U::allocate>*);
    template<typename U>
    static char (&test(...))[2];
    static bool const value = sizeof(test<T>(0)) ==1;
};

Следует отметить, что при этом обнаруживается другой тип распределителя, который имеет void* allocate(std::size_t) в качестве функции-члена, которая является нестандартной (возможно, некоторый необработанный распределитель памяти).

Далее у меня есть неполный тип и std :: allocator для этого неполного типа.

struct test;
typedef std::allocator<test> test_alloc;

И я проверяю, ищу ли я test_alloc.

struct kind_of_alloc
{
   const static bool value =  has_alloc<test_alloc>::value;
};

Конечно, struct test будет завершено, когда я буду «использовать» test_alloc, например,

#include "test_def.hpp"//contains the code posted above
struct test{};

void use()
{
    test_alloc a;    
}

в другом модуле компиляции. Однако, когда происходит тест has_alloc, компилятор пытается создать экземпляр функции allocate для std :: allocator и находит, что sizeof неполного типа используется внутри тела функции, и вызывает серьезную ошибку. Кажется, что ошибка не возникает, если реализация allocate отделена и включена отдельно в точке использования, такой как

template<typename T>
T* alloc<T>::allocate(std::size_t n)
{
      return (T*)operator new(sizeof(T)*n);
}
void use()
{
    test_alloc a;
    a.allocate(2);
}

А test_def.hpp содержит

template<typename T>
struct alloc
{
  T* allocate(std::size_t n);
};

Однако, хотя я могу сделать это для alloc<T>, для std::allocator это невозможно, так как выделение реализации невозможно. Что я ищу, так это возможность проверить, существует ли функция с void* allocate(size_t) в test_alloc. Если нет, это будет отрицательный результат, и если да, то есть. если сигнатура функции совпадает, даже если ее нельзя создать там, проверьте положительный результат.

1 Ответ

0 голосов
/ 18 июня 2010

Нет, SFINAE действует только при разрешении перегрузки.Как только решение принято и компилятор начинает создание экземпляра функции, SFINAE завершается.

Редактировать: и получение адреса функции создает его экземпляр.

...