Gcc SFINAE使用模板非类型引用参数失败
考虑以下代码:Gcc SFINAE使用模板非类型引用参数失败,gcc,clang,c++17,sfinae,non-type,Gcc,Clang,C++17,Sfinae,Non Type,考虑以下代码: constexpr int XX = 10; template < auto& II > struct Ban { }; template < auto& II > std:: true_type test(Ban<II>*); std::false_type test(...); constexpr int XX=10; 模板structban{}; 模板 标准:真_型试验(Ban*); 标准:假_型试验(…); 以及:
constexpr int XX = 10;
template < auto& II > struct Ban { };
template < auto& II >
std:: true_type test(Ban<II>*);
std::false_type test(...);
constexpr int XX=10;
模板structban{};
模板
标准:真_型试验(Ban*);
标准:假_型试验(…);
以及:
使用BB=decltype(test(std::declval());
在这里,我期望BB
是std::true\u type
,但是gcc-8.3
和clang-8.0
都是std::false\u type
。这是这些编译器中的错误吗
请注意,当我将auto&
更改为auto
时,BB
变为std::true\u type
。还要注意的是,对于gcc
来说,如果我使用int const
而不是auto
,情况是一样的,因此int const&
会产生std::false\u类型
,int const
会产生std::true\u类型
,而clang
会产生std::true\u类型
。你可以找到活生生的例子
使用非类型引用的模板进行此类SFINAE是否有解决方法?关键是要有一个像
isinstationofban
这样的实用程序,而不是您想要的decltype(auto)
:
#包括
constexpr int XX=10;
模板结构Ban{};
模板
标准:真_型试验(Ban*);
标准:假_型试验(…);
int main()
{
使用BB=decltype(test(std::declval());
//^^小心支架!
静态断言(std::is_same_v);
返回0;
}
对于第一个问题,clang可能需要在
auto&
之前使用const
说明符来实现const正确性(constepr变量也可能是const
) 我真的看不到标准中有任何东西清楚地说明了模板参数推断如何对包含占位符类型的非类型模板参数起作用。我怀疑这是一个巨大的错误,不是吗?@johanneschaub litb确实,我的回答中没有明确说明是不是:)<代码>自动&也应与常量
匹配。或许可以做为参考。谢谢!我担心模板参数中的auto
会无缘无故地使用与其他地方的auto
不同的规则。因为这是C++,这一点我都不感到惊讶。
using BB = decltype(test(std::declval<Ban<XX>*>()));
#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;
}