sfinae实例化一个函数体吗?

时间:2010-06-18 17:21:27

标签: c++ templates sfinae

我希望使用通常的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测试发生时,编译器尝试实例化std :: allocator的allocate函数,并发现在函数体内使用了不完整类型的size,并导致硬错误。   如果分配的实现分开并在使用点单独包含,如

,似乎不会发生错误
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 :(得分:0)

不,SFINAE仅在重载解析期间有效。一旦做出决议并且编译器开始实例化SFINAE的功能就结束了。

编辑:并取一个函数的地址实例化它。