据我所了解,以下内容应该是符合C++20标准的:
template<int i> struct A {};
struct B
{
constexpr int one() const { return 1; }
};
template<B b> A<b.one()> f() { return {}; }
void test()
{
f<B{}>();
}
MSVC 不支持这种写法(指 Visual Studio 2022,但据 godbolt 显示所有版本都存在某些问题,包括 v19.28 出现 ICE):
error C2672: 'f': no matching overloaded function found
error C2770: invalid explicit template argument(s) for 'A<'function'> f(void)'
无论是clang还是gcc都可以接受它。
作为一种解决方法,将函数评估包装起来就可以了。
template<B b>
struct WrapOne
{
static constexpr int value = b.one();
};
template<B b> A<WrapOne<b>::value> f() { return {}; }
使用内联的constexpr变量也可以进行包装:
template<B b> inline constexpr auto one_v = b.one();
template<B b> A<one_v<b>> f() { return {}; }
我假定这是MSVC的一个bug?我在MS开发者社区网站上没有找到相关信息,但感觉这是其他人一定遇到过的非常基本的问题。
还有其他聪明的解决方法吗?