gpt4 book ai didi

c++ - 为什么这个编译,模板推导应该失败?

转载 作者:行者123 更新时间:2023-11-30 03:38:26 25 4
gpt4 key购买 nike

我正在尝试编写序列化程序。编译以下代码:

#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

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. The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression. [ Note: Before the lifetime of the reference has started or after it has ended, the behavior is undefined (see [basic.life]). — end note ]

我认为参数类型 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

关于c++ - 为什么这个编译,模板推导应该失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39611311/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com