为什么这个编译,模板演绎会失败
Why does this compile, Template deduction should fail?
我正在尝试编写一个序列化器。编译以下代码:
#include <string>
#include <fstream>
#include <type_traits>
#include <map>
#include <iostream>
class SpaceStream
{
public:
SpaceStream(const std::string& filename)
:
m_file(filename)
{
}
template<typename T>
typename std::enable_if<std::is_class<T>::value>::type
Add(const std::string& key, const T& t)
{
m_file << key;
m_file << ":{";
t.Serialise(*this);
m_file << "},";
}
template<typename T>
typename std::enable_if<!std::is_class<T>::value && !std::is_pointer<T>::value && !std::is_reference<T>::value>::type
Add(const std::string& key, const T t)
{
m_file << key;
m_file << ':';
m_file << t;
m_file << ',';
}
private:
std::ofstream m_file;
std::map<std::string,std::string> m_pointerObj;
};
class ISerialise
{
public:
virtual void Serialise(SpaceStream& stream) const = 0;
};
class Test1 : public ISerialise
{
public:
int m_x;
int& m_rx;
Test1(int& x)
:
m_x(x), m_rx(x)
{
}
virtual void Serialise(SpaceStream& stream) const
{
stream.Add("x",m_x);
stream.Add("xr",m_rx);
}
};
int main()
{
int j = 13;
Test1 test(j);
j = 23;
SpaceStream ss("somefile.ss");
ss.Add("testobj",test);
}
我本以为这行:
stream.Add("xr",m_rx);
将会失败,因为两个Add
函数,一个特别检查类型不是类,另一个检查它不是引用。m_rx
是一个引用类型,所以它应该失败?
编辑我现在明白,类型实际上是一个值,而不是一个引用。我需要能够识别引用,以便我可以跟踪它们(我只想序列化数据一次,并引用它)。
根据expr#5
如果表达式的初始类型是"对T的引用"([dcl。[dcl.init.ref]),则在进一步分析之前将类型调整为T。表达式指定由引用表示的对象或函数,表达式是左值或右值,具体取决于表达式。[注意:在引用的生命周期开始之前或结束之后,行为是未定义的(参见[basic.life])。]
我认为实参类型A
在执行模板实参演绎时永远不会是引用类型。一个简单的测试可以是
#include <type_traits>
template <class T> void f(T) { static_assert(std::is_same<T, int &>::value, "ERROR"); }
template <class T> void ff(T) { static_assert(std::is_same<T, int>::value, "ERROR"); }
int main(int argc, const char **argv) {
int i;
int &r = i;
f(r); // static assert failed
ff(r); // static assert success
return 0;
}
我能想到的一个遍历是使用decltype
f<decltype(r)>(r); // static assert success now
相关文章:
- 如果没有malloc,链表实现将失败
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- 视图中的参数推导失败:take_while
- 链接到自行创建的dll失败
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- 使用显式模板参数列表和 [temp.arg.explicit]/3 的函数调用的演绎失败
- λ类型演绎失败
- SFINAE使用演绎,但用替换失败
- 可变参数模板构造函数的演绎指南失败
- 模板作为函数模板的参数 - 演绎失败
- 错误:没有匹配的函数调用[…]注意:模板参数演绎/替换失败
- 模板参数演绎/替换失败
- 为什么decltype返回类型在递归模板中失败,而返回类型演绎却工作得很好?
- 为什么这个编译,模板演绎会失败
- c++模板参数演绎失败
- 为什么模板参数演绎/替换在这里失败?
- Boost::odeint演绎/替换失败
- 为什么迭代器类型演绎失败
- 模板参数演绎失败