[英]Why does this compile, Template deduction should fail?
I'm attempting to write a serialiser. 我正在尝试编写序列化程序。 The following code compiles:
以下代码编译:
#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);
}
I'd have thought that this line: 我以为这行:
stream.Add("xr",m_rx);
would have failed because of the two Add
functions, one specifically checks that the type isn't a class, the other checks that it's not a reference. 会因为两个
Add
函数而失败,一个函数专门检查该类型不是类,另一个专门检查该类型不是引用。 m_rx
is a reference type, so it should fail? m_rx
是引用类型,因此应该失败?
EDIT I understand now that the type is actually a value and not a reference. 编辑我现在知道类型实际上是一个值而不是引用。 I need to be able to identify references so that I can keep track of them (I only want to serialise the data once, and reference it).
我需要能够标识引用,以便跟踪它们(我只想序列化数据一次,然后引用它)。
If an expression initially has the type “reference to T” ([dcl.ref], [dcl.init.ref]), the type is adjusted to T prior to any further analysis.
如果表达式最初的类型为“对T的引用”([dcl.ref],[dcl.init.ref]),则在进行任何进一步分析之前,将类型调整为T。 The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression.
表达式指定由引用表示的对象或功能,并且表达式取决于表达式是左值还是x值。 [ Note: Before the lifetime of the reference has started or after it has ended, the behavior is undefined (see [basic.life]).
[注意:在引用的生存期开始之前或结束之后,行为是不确定的(请参阅[basic.life])。 — end note ]
—尾注]
I think the argument type A
will never be a reference type when performing template argument deduction. 我认为执行模板参数推论时,参数类型
A
永远不会是引用类型。 A simple test could be 一个简单的测试可能是
#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;
}
One walk-around I can think of is explicitly specify template argument using decltype
我可以想到的一种解决方法是使用
decltype
显式指定模板参数
f<decltype(r)>(r); // static assert success now
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.