我尝试在 Visual Studio 2013 中编译以下程序并得到了 C2686: cannot overload static and non-static member functions
错误。
#include <iostream>
#include <type_traits>
struct foo
{
template<bool P>
static std::enable_if_t<P> bar()
{
std::cerr << "P is true\n";
}
template<bool P>
std::enable_if_t<!P> bar()
{
std::cerr << "P is false\n";
}
};
int main()
{
foo f;
f.bar<true>();
}
我熟悉这个编译器错误 — 请参阅 this StackOverflow answer , 但惊讶地看到与 SFINAE 相关的错误,编译器将始终丢弃重载集中的两个重载之一。
Visual Studio 2013 是否正确遵循此处的标准,或者是否可以结合 SFINAE 在静态上重载?
编辑:将上面的示例与返回类型重载进行对比
如果没有 SFINAE,您将无法重载 static
,也无法重载返回类型。但是,Visual Studio 2013 支持结合 SFINAE 重载返回类型。
以下程序与上面的程序相同,但删除了 static
并更改了第二个 foo::bar
声明的返回类型,编译正确。
#include <iostream>
#include <type_traits>
struct foo
{
template<bool P>
std::enable_if_t<P> bar()
{
std::cerr << "P is true\n";
}
template<bool P>
std::enable_if_t<!P, int> bar()
{
std::cerr << "P is false\n";
return 42;
}
};
int main()
{
foo f;
f.bar<true>();
}
在我看来,Visual Studio 2013 将这两种情况中的一种弄错了,但我希望语言律师可以提供明确的答案。
最佳答案
令人惊讶的是,MSVC 是正确的。 (我知道,震惊。)[over.load]/p1-2:
1 Not all function declarations can be overloaded. Those that cannot be overloaded are specified here. A program is ill-formed if it contains two such non-overloadable declarations in the same scope. [Note: This restriction applies to explicit declarations in a scope, and between such declarations and declarations made through a using-declaration (7.3.3). It does not apply to sets of functions fabricated as a result of name lookup (e.g., because of using-directives) or overload resolution (e.g., for operator functions). —end note]
2 Certain function declarations cannot be overloaded:
- Function declarations that differ only in the return type cannot be overloaded.
- Member function declarations with the same name and the same parameter-type-list cannot be overloaded if any of them is a
static
member function declaration (9.4). Likewise, member function template declarations with the same name, the same parameter-type-list, and the same template parameter lists cannot be overloaded if any of them is astatic
member function template declaration. [...]- [...]
两个bar()
声明有相同的名字,相同的parameter-type-list,和相同的模板参数列表,至少其中一个是 static
,因此不能重载。
关于c++ - 静态重载与 SFINAE 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31062892/