Clang vs. GCC:未评估上下文中的错误会中断 SFINAE
Clang vs. GCC: Error in unevaluated context breaks SFINAE
在继续我上一个问题的工作时,我遇到了 clang 和 GCC 的不同行为。
我需要检查成员函数指针,因为我需要知道该函数是否被继承。
在SFINAE上下文中比较成员函数指针时,成员函数Foo::foo()
存在,但其主体包含最终无法编译的代码(x.hello()
)。
以下代码使用 clang 进行编译。然而,GCC 似乎评估了 Foo::foo()
的函数体并以错误('struct Caller' has no member named 'hello'
)退出,尽管处于未评估的 SFINAE 上下文中(或者我希望如此)。
#include <iostream>
#include <type_traits>
struct Foo
{
template <typename T> void foo(T&& x) { x.hello(); }
};
struct Caller
{
template <typename T>
auto call(T&& x) -> decltype(
std::enable_if_t<
std::is_same<
decltype(&T::template foo<decltype(*this)>),
void (T::*)(decltype(*this))
>::value
>())
{
//x.foo(*this);
}
};
int main()
{
Caller c;
c.call(Foo());
}
我测试了:
- 叮当 3.8.0
- g++ 6.1.0
两者的编译器选项:-std=c++14 -O2 -Wall -pedantic -pthread
现场示例
我的问题:
- 谁是对的?叮当还是海湾合作委员会?
- 如何获取代码以使用 GCC 进行编译?
回答第二个问题
如何获取代码以使用 GCC 进行编译?
我会简化传递给decltype()
的表达式。如果call
方法的编译依赖于x.foo(*this);
的编译,那么这就是你应该使用的。
struct Foo
{
template <typename T> void foo(T&& x) { x.hello(); }
};
struct Caller
{
template <typename T>
auto call(T&& x, int) -> decltype(x.foo(*this))
{
//x.foo(*this);
}
template <typename T>
void call(T&&, char){ std::cout << "hello" << std::endl;}
};
int main()
{
Caller c;
c.call(Foo(), 0);
}
在这里演示。
我认为 op 对 gcc 的问题在于函数的地址(如果没有明确采用,则会衰减到函数指针)。我认为这是标准中的一个极端情况。如果需要方法Foo::foo
,则x.hello()
需要存在(编译);一般来说,获取某物的地址可以满足这一点,但在未评估的上下文中(decltype()
),我不确定这是否适用 - 当然 clang 不需要它存在(MSVC 也不要求)。
在这方面,
谁是对的?叮当还是海湾合作委员会?
我怀疑 clang 实现了对标准的更宽松的解读,并且可能更正确的解读。decltype()
的操作数是未计算的操作数,请参阅 [dcl.type.simple]/4;
decltype 说明符的操作数是未计算的操作数(子句 [expr])。
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- 代码在main()中运行,但在函数中出现错误
- 释放错误后堆使用
- (C++)分析树以计算返回错误值的简单算术表达式
- Project Euler问题4的错误解决方案
- 我的字符计数代码计算错误.为什么
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 尝试导入pybind-opencv模块时出现libgtk错误
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 在某些循环内使用vector.push_back时出现分段错误
- MSVC多行宏编译器错误
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 错误:未在此范围内声明'reverse'