CTAD 可以在模板类的成员内部使用吗?

alf*_*lfC 3 c++ class-template c++20 ctad

C++ 有一个有用的功能,即模板参数隐含在模板类内的代码中A。然而,对于建筑来说,这似乎与 CTAD 发生冲突。

如何让 CTAD 优先?

例如,在这里,成员中有一个错误f,因为A它被解释为A<T>where Tis std::string,而不是从参数 推导出来double

#include<string>

template<class T>
struct A {
    A(T const& t) {}
    auto f() {return A{5.0};}  // error here triggered by line 11 `auto a2 = a1.f();`
};

int main() {
    A a1{std::string{"hello"}};
    auto a2 = a1.f();
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/3nc7nev3o

Nat*_*ica 5

您需要使用 use::A告诉编译器使用全局范围中的名称,而不是使用类范围中的A名称,这只是 的简写。这给你:AA<T>

#include<string>

template<class T>
struct A {
    A(T const& t) {}
    auto f() {return ::A{5.0};}  // uses CTAD to return A<double>
};

int main() {
    A a1{std::string{"hello"}};
    auto a2 = a1.f();
}
Run Code Online (Sandbox Code Playgroud)

正如这个实例所示。


另一种选择是向类类型添加私有别名,然后根据需要在函数中使用该别名。这给你:

#include<string>

template<class T>
struct A {
private:
    template <typename U>
    using NewA = A<U>;
public:
    A(T const& t) {}
    auto f() {return NewA{5.0};}  // uses CTAD to return A<double>
};

int main() {
    A a1{std::string{"hello"}};
    auto a2 = a1.f();
}
Run Code Online (Sandbox Code Playgroud)

可以看到蜜蜂在这里工作