确定类型是否具有特定的成员函数签名
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;
}
此代码为字符串类生成一个编译错误,指出这两个重载都无法转换所有参数类型。然而,对于向量来说它编译得很好。当参数不是 InsertSig 类型时,重载解析不应该选择 CheckInsert(...) 吗?
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;
}
This code generates a compile error for the string class saying that none of the 2 overloads could convert all argument types. However, for vector it compiles fine. Shouldn't overload resolution choose CheckInsert(...) whenever the parameter isn't of type InsertSig?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
std::string::insert
不采用const char&
参数,而仅采用char
。此外,根据实现在 C++11 支持方面的进展,所有容器都可能使用 const_iterator(而不是迭代器)来指示位置。
The
std::string::insert
doesn't take aconst char&
parameter, but just achar
.Also, depending on how far the implementation has has come in its C++11 support, all containers might use a const_iterator (instead of iterator) to indicate the position.
请尝试这样做:
它不起作用的原因是,在您的版本中,获取插入函数的地址将在调用站点失败,而不是在替换时失败(这不是错误)。上面将确保,如果类型 U(模板化为 T)无法用于获取要插入的可转换为给定签名的成员函数指针,它将无法替换虚拟参数,因此将恢复为省略号版本。
Try this instead:
The reason why it doesn't work is because, in your version, taking the address of the insert function will fail at the call site, not at the substitution (which is not an error). The above will make sure that if the type U (templated to T) cannot be used to obtain a member function pointer to insert which is convertable to the given signature, it will fail to substitute for the dummy parameter, and thus, revert to the ellipsis version.