gpt4 book ai didi

C++ noexcept 声明更改模板推导

转载 作者:可可西里 更新时间:2023-11-01 17:40:02 26 4
gpt4 key购买 nike

我正在修补以确认 Effective Modern C++ 第 91 页上的示例,我遇到了一个似乎很奇怪的问题。这段代码

template<typename C>
void doStuff(C& a, C& b) noexcept(noexcept(doStuff(a.front(), b.front()))) {
std::cout << "container version" << std::endl;
}

template<>
void doStuff<int>(int& x, int& y) noexcept {
std::cout << "int version" << std::endl;
}

int main() {
vector<int> v1 = {1, 2, 3};
vector<int> v2 = {4, 5, 6};
int x = 5;
int y = 6;
doStuff(x, y);
doStuff(v1, v2);
}

给我一​​个错误,比如

error: request for member ‘front’ in ‘a’, which is of non-class type ‘int’ void doStuff(C& a, C& b) noexcept(noexcept(doStuff(a.front(), b.front()))) {

因此,似乎正在调用 doStuff 的顶级版本,即使 a.front() 和 b.front() 应该返回对 int 的引用。如果我从代码中删除所有 noexcept 声明,我将得到预期的输出。

这是 gcc 5.4。

我做错了什么?

谢谢

最佳答案

问题是,此时查找名称时:

template<typename C>
void doStuff(C& a, C& b) noexcept(noexcept(doStuff(a.front(), b.front()))) {
// ^^^^^^^

只会找到一个 doStuff():您的函数模板。特化尚未宣布,因此不考虑。

要做的第一件事就是简单地避免特化。他们很尴尬。但是真正的解决方法是为了依赖于参数的查找目的而坚持一个额外的空类型。这将向 noexcept 查找添加一个相关名称,该名称将延迟调用直到实例化:

namespace N {
struct adl { };

void doStuff(adl, int& , int& ) noexcept {
std::cout << "int version" << std::endl;
}

template<typename C>
void doStuff(adl, C& a, C& b) noexcept(noexcept(doStuff(adl{}, a.front(), b.front()))) {
std::cout << "container version" << std::endl;
}
}

template <class C>
void doStuff(C& a, C& b) noexcept(noexcept(doStuff(N::adl{}, a, b)))
{
doStuff(N::adl{}, a, b);
}

关于C++ noexcept 声明更改模板推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39024705/

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