does sfinae instantiates a function body?

此生再无相见时 提交于 2019-12-10 17:28:43

问题


I want to detect existence of a specific member function for a class, using the usual SFINAE trick.

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;
};

It should be noted that this detects a different kind of allocator which has void* allocate(std::size_t) as member function which are non standard (probably some raw memory allocator).

Next, I have an incomplete type and an std::allocator for that incomplete type.

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

And I am checking whether the test_alloc is the one I am looking for.

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

Surely struct test will be complete when I will "use" test_alloc such as

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

void use()
{
    test_alloc a;    
}

in another compilation unit. However when the has_alloc test happens,the compiler tries to instantiate the allocate function for std::allocator and finds that sizeof an incomplete type is used inside function body, and causes a hard error. It seems that the error doesn't occur if the implementation of allocate separated and included separately at the point of use such as

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);
}

And test_def.hpp contains

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

However while I can do this for alloc<T> , it is not possible for std::allocator as separating out the implementation is not possible. What I am looking for is it possible to test whether a function with void* allocate(size_t) exists in test_alloc. If not, it will test negative, and if yes ,i.e. if the function signature matches, even if it can not be instantiated there, test positive.


回答1:


No, SFINAE is only in effect during overload resolution. Once a resolution has been made and the compiler begins instantiating the function SFINAE is over.

Edit: and taking the address of a function instantiates it.



来源:https://stackoverflow.com/questions/3071785/does-sfinae-instantiates-a-function-body

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!