static_cast 的替换失败不是错误(SFINAE)问题
鉴于:
class Hokey
{
public:
explicit C(int i): i_(i) { }
template<typename T>
T& render(T& t) { t = static_cast<T>(i_); return t; }
private:
unsigned i_;
};
如果我尝试:
Hokey h(1);
string s;
h.render(s);
Codepad 在静态转换上给我一个错误:
t.cpp: In member function 'T& Hokey::render(T&) [with T = std::string]':
t.cpp:21: instantiated from here
Line 11: error: no matching function for call to 'std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(unsigned int&)'
似乎应该说有没有 Hokey::render
匹配。
当然,如果我提供有效的重载,一切都会正常。 但鉴于下面的代码,您取消注释该行, codepad chokes Again:
string& render(string& s) const {
ostringstream out;
out << i_;
// s = out.str();
return s;
}
不会 SFINAE 说 - 在第一种情况下 - 渲染中的问题不应该是错误,而不是缺少有效的渲染应该是错误?
Given:
class Hokey
{
public:
explicit C(int i): i_(i) { }
template<typename T>
T& render(T& t) { t = static_cast<T>(i_); return t; }
private:
unsigned i_;
};
If I try:
Hokey h(1);
string s;
h.render(s);
Codepad gives me an error on the static cast:
t.cpp: In member function 'T& Hokey::render(T&) [with T = std::string]':
t.cpp:21: instantiated from here
Line 11: error: no matching function for call to 'std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(unsigned int&)'
It seems like it should say that there is no Hokey::render
to match.
Of course, if I supply a valid overload, everything works.
But given the code below, you uncomment the line, codepad chokes again:
string& render(string& s) const {
ostringstream out;
out << i_;
// s = out.str();
return s;
}
Doesn't SFINAE say that - in the first case - the problem within render should not be the error, rather the absence of a render that works should be the error?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这只是在重载解析期间不是错误。换句话说,它会推迟给您一个错误,直到确定该调用肯定无法正常工作为止。之后,这是一个错误。
还应该注意的是,重载解析(以及 SFINAE)仅查看函数签名,而不是定义。所以这总是会失败:
对于函数签名来说,任何一个模板替换都没有错误,因此两个函数都可以调用,即使我们知道第一个函数会失败而第二个函数不会失败。所以这会给你一个不明确的函数调用错误。
您可以使用
boost::enable_if
(或 C++0x 中的std::enable_if
,相当于boost::enable_if_c
)显式启用或禁用函数>)。例如,您可以使用以下方法修复前面的示例:It's only not an error during overload resolution. In other words, it puts off giving you an error until it's sure the call definitely isn't going to work. After that, it's an error.
It should also be noted that overload resolution (and therefore SFINAE) only looks at the function signature, not the definition. So this will always fail:
There are no errors for either template substitution — for the function signatures — so both functions are okay to call, even though we know the first one will fail and the second won't. So this gives you an ambiguous function call error.
You can explicitly enable or disable functions with
boost::enable_if
(orstd::enable_if
in C++0x, equivalent toboost::enable_if_c
). For example, you might fix the previous example with: