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;
}
此代码为字符串类生成编译错误,指出2个重载都不能转换所有参数类型。然而,对于矢量,它编译很好。如果参数不是InsertSig类型,那么不应该重载决策选择CheckInsert(...)
答案 0 :(得分:2)
请改为尝试:
#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)不能用于获取可转换为给定签名的插入的成员函数指针,它将无法替换伪参数,因此,将恢复为省略号版本。
答案 1 :(得分:0)
std::string::insert
不会使用const char&
参数,而只需char
。
此外,根据C ++ 11支持实现的程度,所有容器都可以使用const_iterator(而不是迭代器)来指示位置。