我创建了一个 C++ 概念,用于检查模板类 是否T可以从固定类 构造CData&。
T = CThing对于无法从 构造的特定对象CData&,我的概念似乎传递了对该类的引用,即T = CThing&,这不是我想要的,因为它会导致我的模板解析不正确。
不仅如此,我不知道为什么这段代码甚至可以编译,因为它成功地CThing&从引用初始化了引用CData&,这是一个完全不相关的类。
我在下面添加了一个 MWE 来展示我的意思。
据我所知:
return T(data);T当isCThing&且 data 为 时应该是不可能的CData&,但这是有效的。IsConstructable应该失败CThing&,但它通过了。std::cout << thing.Value甚至不应该到达,但它被调用(并产生垃圾输出)。有人可以解释一下发生了什么事吗?
#include <iostream>
struct CThing { int Value; };
struct CData { };
template <typename T> concept IsConstructable = requires(CData& data, T t) { T(data); };
template<typename T> struct CSerialiser {};
template <IsConstructable T>
struct CSerialiser<T>
{
static T Deserialise(CData& data)
{
return T(data);
};
};
int main()
{
CData data;
CThing& thing = CSerialiser<CThing&>::Deserialise(data);
std::cout << thing.Value; // garbage out
}
Run Code Online (Sandbox Code Playgroud)
针对下面周伟军的回答,我注意到等效的非模板化代码的行为符合预期并且无法编译:
CData data;
CData& refData;
CThing& thing(refData); // error C2440
Run Code Online (Sandbox Code Playgroud)
这是 C 风格和函数风格转换不好的另一个例子。
T(data)当然可以编译T=CThing&类型的数据CData&,因为你正在reinterpret_cast这里做一个。
如果您想说T应该可以从data或其他任何内容构建,请使用库提供的标准概念:std::constructible_from。不要自己卷。该标准考虑了您可能没有考虑到的边缘情况。
如果您必须自己动手,请从 cppreference 上的参考实现开始,而不是从头开始。
| 归档时间: |
|
| 查看次数: |
60 次 |
| 最近记录: |