考虑以下代码:
constexpr int XX = 10;
template < auto& II > struct Ban { };
template < auto& II >
std:: true_type test(Ban<II>*);
std::false_type test(...);
和:
using BB = decltype(test(std::declval<Ban<XX>*>()));
在这里,我期望BB
为std::true_type
,但对于std::false_type
和gcc-8.3
来说都是clang-8.0
。这是这些编译器中的错误吗?
请注意,当我将BB
更改为std::true_type
时,auto&
变成了auto
。另请注意,如果我使用gcc
而不是int const
,则auto
的情况相同,因此int const&
的收益为std::false_type
,而int const
的收益为到std::true_type
,而对于clang
int const&
产生std::true_type
。您可以找到实时示例here。
是否有一种解决方法,可以使用非类型引用模板来进行这种SFINAE?关键是要拥有IsInstantiationOfBan
之类的实用工具。
答案 0 :(得分:2)
您可能想要auto &
而不是decltype(auto)
:
#include <type_traits>
constexpr int XX = 10;
template <decltype(auto) II > struct Ban { };
template <decltype(auto) II >
std::true_type test(Ban<II>*);
std::false_type test(...);
int main()
{
using BB = decltype(test(std::declval<Ban<(XX)>*>()));
// ^ ^ be careful for brackets!
static_assert(std::is_same_v<BB, std::true_type>);
return 0;
}
在您遇到第一个问题时,c语可能要求const
之前的auto &
修饰符来实现const正确性(constexpr变量也可能是const
)。 [example]。