确定类型是否具有特定的成员函数签名

Determine if a type has particular member function signature

本文关键字:成员 函数 类型 是否      更新时间:2023-10-16
template<typename U> struct CheckSignature {
    enum {SizeTrue = 1, SizeFalse = 2};
    typedef char ReturnTrue[SizeTrue];
    typedef char ReturnFalse[SizeFalse];
    typedef typename U::iterator (U::*InsertSig)(typename U::iterator, typename const U::value_type &);
    static ReturnTrue &CheckInsert(InsertSig);
    static ReturnFalse &CheckInsert(...);
    static const bool value = (sizeof(CheckInsert(&U::insert)) == sizeof(ReturnTrue));
};
int main() {
    CheckSignature<std::string >::value; //compile error
    CheckSignature<std::vector<int> >::value; // OK
    return 0;
}

这段代码为string类生成了一个编译错误,指出这两个重载都不能转换所有参数类型。然而,对于vector,它编译得很好。当参数不是InsertSig类型时,重载解析不应该选择checkinset(…)吗?

试试这个:

#include <string>
#include <vector>
#include <iostream>
template<typename U> struct CheckSignature {
    enum {SizeTrue = 1, SizeFalse = 2};
    typedef char ReturnTrue[SizeTrue];
    typedef char ReturnFalse[SizeFalse];
    typedef typename U::iterator (U::*InsertSig)(typename U::iterator, typename U::value_type const &);
    template <InsertSig f> struct dummy_type { };
    template <typename T>
    static ReturnTrue &CheckInsert(T*, dummy_type<&T::insert> dummy = dummy_type<&T::insert>());
    static ReturnFalse &CheckInsert(...);
    static const bool value = (sizeof(CheckInsert(((U*)0))) == sizeof(ReturnTrue));
};
int main() {
    if(CheckSignature<std::string >::value) {
      std::cout << "String class has proper insert function" << std::endl;
    }; //OK, does not print, as expected.
    if(CheckSignature<std::vector<int> >::value) {
      std::cout << "Vector class has proper insert function" << std::endl;
    }; //OK, does print, as expected.
    return 0;
}

它不起作用的原因是,在您的版本中,获取插入函数的地址将在调用站点失败,而不是在替换(这不是错误)。以上将确保,如果类型U(模板化为T)不能用于获取可转换为给定签名的成员函数指针来插入,则它将无法替换哑形参,因此,将恢复为省略号版本。

std::string::insert不接受const char&参数,而只接受char参数。

而且,根据实现在c++ 11中的支持程度,所有容器都可以使用const_iterator(而不是iterator)来指示位置。