我可以禁用SFINAE吗?
Can I disable SFINAE?
假设我有这样一个程序
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;
}
生活例子我可能出于各种原因需要auto
说明符,但是上面的程序产生以下错误:
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'");
}
};
get_type
(从不失败)和has_type
(使用SFINAE)是无处不在的标准练习。
相关文章:
- 函数向量_指针有不同的原型,我可以构建一个吗
- 我可以使用 g++ 进行三种比较 (<=>) 吗?
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 为什么我可以通过引用修改常量返回
- 我可以在 C++ 中的函数体之外进行操作吗?
- 我可以重新分配/覆盖std::字符串吗
- C++-我可以创建另一个类的成员并在构造函数中使用它吗
- 我可以将调用类的"this"传递给 lambda 函数吗?
- 我可以检测和更改 gcc/g++ 中结构的当前数据对齐设置吗?
- 为什么我可以使用比分配的内存更多的内存
- 在一个读写器队列中,我可以用volatile替换原子吗
- 我可以把基础班提升为儿童班吗
- 我可以做些什么来消除或最小化这种将提供相同功能和行为的代码重复
- SFINAE 消除、Constexpr 和函数模板:我可以将声明和定义分开吗?
- 我可以使用SFINAE来检测模板类成员函数吗
- 我可以禁用SFINAE吗?
- 我可以使用 SFINAE 有选择地定义模板类中的成员变量吗?
- 我可以在所有 MSVC >= 2013 上安全地使用哪些 SFINAE 技巧?