c++ - gcc 中带有 const& 模板参数的错误?

标签 c++ templates c++17 auto non-type

考虑 this代码:

#include <type_traits>

template < int > struct II { };
template < const int& > struct RR { };

template < template <auto> typename Class, typename Type > struct Check : std::false_type { };
template < template <auto> typename Class, auto NonTypes > struct Check<Class,Class<NonTypes>> : std::true_type { };

constexpr int TEN = 10;
constexpr const int& REF = TEN;

static_assert(Check<II,II<TEN>>::value); // passes
static_assert(Check<RR,RR<REF>>::value); // FAILS!?

我正在使用 gcc-7.0.1 和 here是活生生的例子。问题是这是编译器错误还是我做错了什么?

最佳答案

让我们稍微简化一下示例:

template <template <auto> class C, auto N>
void foo(C<N> ) { }

int main() {
    foo(II<TEN>{} ); // ok
    foo(RR<REF>{} ); // error
}

问题是正常的auto扣除规则适用于N ,在 REF 中推导出来案例类型 int .非类型模板参数类型不匹配 - int const& - 和参数 - int , 所以它的格式不正确。

如果我们将示例翻转为 auto const& N (或 auto&& N ),那么它将是 II<TEN>出于同样的原因,调用将是格式错误的——我们现在得到一个引用类型的模板参数,但该参数是一个非引用类型。

您无法使用当今语言中的一个函数来处理这两种情况。你需要两个:

template <template <auto> class C, auto N>     void foo(C<N> ) { } // #1
template <template <auto&&> class C, auto&& N> void foo(C<N> ) { } // #2

int main() {
    foo(II<TEN>{} ); // ok: calls #1
    foo(RR<REF>{} ); // ok: calls #2
}

与您的原始示例类似:您需要一种针对值的特化和一种针对引用的特化。 C 的模板-模板非类型参数中的引用可能没有必要。

关于c++ - gcc 中带有 const& 模板参数的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42133141/

相关文章:

c++ - 替换为 cpp 中基于 getch 的代码块

c++ - 推导引用模板参数的类型

c++ - 从线程内 fork 是否安全?

c++ - 在 Windows 控制台中获取按键

c++ - 自定义类的 std::make_pair 段错误

c++ - 模板模板参数简单示例

c++ - std::invoke - 完美转发仿函数

c++ - 确定列和行

java - JNI 方法 : formal argument lists differ in length

c++ - GCC 4.9 中的模板实例化错误,在 GCC 4.8 中工作正常