Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Gcc SFINAE使用模板非类型引用参数失败_Gcc_Clang_C++17_Sfinae_Non Type - Fatal编程技术网

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;
}