gpt4 book ai didi

c++ - 具有非类型参数包的模棱两可的类模板实例化

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:14:46 24 4
gpt4 key购买 nike

我试图专门化 Expr:

#include <tuple>
#include <type_traits>
#include <iostream>

template<class Tp, class List>
struct Expr {
Expr(){std::cout << "0"<< std::endl;};
};

//specialization #1
template<class Tp, int...i>
struct Expr<Tp,std::tuple<std::integral_constant<int,i>...>> {

Expr(){std::cout << "1"<< std::endl;};
};

//specialization #2
template<int...i>
struct Expr<double,std::tuple<std::integral_constant<int,i>...>> {

Expr(){std::cout << "2"<< std::endl;};
};

int main() {

typedef std::tuple<std::integral_constant<int,1>> mylist;

Expr<double,mylist> test{};

return 0;
}

但是,我遇到了以下编译器错误:

[x86-64 gcc 6.3] error: ambiguous template instantiation for 'struct Expr<double, std::tuple<std::integral_constant<int, 1> > >'
[x86-64 gcc 6.3] error: variable 'Expr<double, std::tuple<std::integral_constant<int, 1> > > test' has initializer but incomplete type

在这里,尤其是第一个错误困扰着我。我试图弄清楚为什么这是一个模棱两可的实例化。

编译器不应该选择 specialization #2 吗?

如果我避免将非类型参数包 int...i 包装在 std::integral_constant 中,它可以毫无问题地进行编译,并且会选择第二个特化。以下示例有效:

#include <tuple>
#include <type_traits>
#include <iostream>

template<class Tp, class List>
struct Expr {
Expr(){std::cout << "0"<< std::endl;};
};

//specialization #1
template<class Tp, class...args>
struct Expr<Tp,std::tuple<args...>> {

Expr(){std::cout << "1"<< std::endl;};
};

//specialization #2
template<class...args>
struct Expr<double,std::tuple<args...>> {

Expr(){std::cout << "2"<< std::endl;};
};

int main() {

typedef std::tuple<std::integral_constant<int,1>> mylist;

Expr<double,mylist> test{};

return 0;
}

最佳答案

这不可能是对的。这是一个 gcc 错误(我找不到它的错误报告,也许还没有报告?)。

你是对的,必须选择专业#2。因为有 2 个匹配的特化,部分排序选择最特化的一个,在您的情况下是 #2(double 作为第一个参数比任何类型作为第一个参数都更特化)。

此外,clang 会编译您的代码 without any problems .

关于c++ - 具有非类型参数包的模棱两可的类模板实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45288574/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com