提问人:alfC 提问时间:7/24/2023 最后编辑:alfC 更新时间:7/24/2023 访问量:102
CTAD 是否可以在模板类的成员中使用?
Can CTAD be used inside a member of the template class?
问:
C++ 具有这个有用的功能,它表示模板参数隐含在模板类内的代码中。
然而,对于建筑来说,这似乎与CTAD相冲突。A
如何使 CTAD 优先?
例如,在这里,成员中存在错误,因为被解释为 where is ,而不是从参数 中推导出来。f
A
A<T>
T
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();
}
答:
5赞
NathanOliver
7/24/2023
#1
您需要 use 告诉编译器使用全局作用域中的名称,而不是使用类作用域中的名称,而类作用域中的名称只是 的简写。这为您提供了:::A
A
A
A<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();
}
如这个实时示例所示。
另一种选择是将私有别名添加到类类型,然后根据需要在函数中使用该别名。这为您提供了:
#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();
}
可以看到蜜蜂在这里工作
评论
0赞
alfC
7/24/2023
嗯,是的,这行得通。godbolt.org/z/hvG1r9EdT。但是,现在该类需要知道它所属的命名空间。不理想。
1赞
NathanOliver
7/24/2023
@alfC 如果你正在定义类,你不知道你在哪个命名空间中吗?
0赞
alfC
7/24/2023
是的,但是如果我以后重构命名空间,我必须更改内部结构。
1赞
NathanOliver
7/24/2023
@alfC我明白了。我刚刚添加了另一个选项
0赞
alfC
7/24/2023
是的,我同时发现了它。(我的回答中有第 2 版)。干杯!
1赞
alfC
7/24/2023
#2
似乎我可以定义一个模板 typedef 并希望 CTAD 能够通过它工作。
#include<string>
template<class T>
struct A;
template<class T> using A_CTAD = A<T>;
template<class T>
struct A {
A(T const& t) {}
auto f() {return A_CTAD{5.0};} // error here triggered by line 11 `auto a2 = a1.f();`
};
int main() {
A a1{std::string{"hello"}};
auto a2 = a1.f();
}
https://godbolt.org/z/hex79s91a
但与使用良好的旧函数相比,这似乎并没有太大的收获。https://godbolt.org/z/j3PTW7MWYmake
版本 2,制作一个内部模板 typedef,还不错。无需转发声明。
template<class T>
struct A {
A(T const& t) {}
private:
template<class TT> using CTAD = A<TT>;
public:
auto f() {return CTAD{5.0};} // error here triggered by line 11 `auto a2 = a1.f();`
};
评论
f
make_A