假设我有这个程序
struct A
{
template <typename T>
static auto fun() -> typename T::type { }
};
struct C
{
// doh! I forgot to add a typedef for type!
};
int main() {
A::fun<C>();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
auto出于各种原因我可能需要说明符,但上述程序会产生以下错误:
Run Code Online (Sandbox Code Playgroud)prog.cpp:13:12: error: no matching function for call to ‘A::fun()’ A::fun<C>();
虽然如此,但它并没有特别有用.在这个例子中很明显我忘了提供一个C::type,但你可以看到,在较大的程序中,这可能会变得非常混乱.
失败的真正原因是在编译器错误消息中埋藏了几行:
prog.cpp:7:15:错误:'struct C'中没有名为'type'的类型
在一个实际的代码库此消息可以是下几百或几千(或数百的千)错误消息(和上述同样大的组消息可能已经从另一变化出现)线.考虑到在真实情况下我们可能甚至不知道要寻找什么,这可能会非常混乱.
一个错误告诉我,A因为C::type没有声明失败的声明会更有帮助.
当然有很多情况下SFINAE是有用且必要的,所以我不想以某种方式完全关闭这种语言功能.但是我可以禁用此特定功能的SFINAE规则吗?
换句话说,我可以在函数声明中添加一些东西来强制编译器尝试编译函数,并在发生替换失败时产生错误吗?
无法禁用 SFINAE。C++ 没有可以随意启用和禁用的功能。有一种方法可以让SF部分永远不会发生,从而让E在其他地方触发。
struct A
{
template <typename T>
static auto fun() -> typename get_type<T>::type {
static_assert(has_type<T>::value, "Template parameter has no type member named 'type'");
}
};
Run Code Online (Sandbox Code Playgroud)
get_type(永远不会失败)和has_type(使用 SFINAE)是到处都有描述的标准练习。
| 归档时间: |
|
| 查看次数: |
242 次 |
| 最近记录: |