我正在学习 C++17decltype(auto)非类型模板参数的新功能。我写了一个简单的代码片段如下:
#include <type_traits>
template<decltype(auto) arg>
struct Foo {};
int
main()
{
constexpr int x = 42;
static_assert(std::is_same_v<Foo<42>, Foo<x>>);
}
Run Code Online (Sandbox Code Playgroud)
据我了解,Foo<42>应该与Foo<x>.
但是,该static_assert语句使用 clang++、MSVC 19.27 编译,但使用 GCC 10.2、MSVC 19.25 编译失败。
我的问题是:为什么编译器的行为不同?标准对此有何评论?
链接到编译器资源管理器:
铛++ https://godbolt.org/z/66M695
gcc https://godbolt.org/z/3v5Mhd
MSVC 19.25 https://godbolt.org/z/qP6v89
MSVC 19.27 https://godbolt.org/z/14aK5Y
我遇到了与嵌套类方法的返回类型推导相关的问题。经过一番挖掘,我将问题缩小到简化版本,如下所示:
#include <type_traits>
struct Alive {};
template<typename T>
auto is_alive_impl(...) -> void;
template<typename T>
auto is_alive_impl(int) -> decltype(std::declval<T>().operator()());
template<typename T>
struct is_alive : std::is_same<decltype(is_alive_impl<T>(0)), Alive> {};
struct Box {
struct Cat {
auto
operator()() {
return Alive{};
}
};
static constexpr auto value = is_alive<Cat>::value; // (1)
};
int main() {
static_assert(is_alive<Box::Cat>::value); // (2)
}
Run Code Online (Sandbox Code Playgroud)
struct is_alive使用函数重载技巧检查一个类是否operator()返回一个Alive实例。
如果没有第 (1) 行,则static_assertat (2) 返回true并且代码按预期进行编译。
但是,我不明白为什么添加第 (1) 行会使第 (2) 行失败。好像我看着盒子并不知何故杀死了那只猫。
这是我的问题: