我正在嘗試編寫一個serialiser。下面的代碼編譯:爲什麼這樣編譯,模板扣除應該失敗?
#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
是一個引用類型,所以它應該失敗?
編輯 我現在明白,類型實際上是一個值,而不是一個參考。我需要能夠識別引用,以便我可以跟蹤它們(我只想將數據序列化一次,並引用它)。
指定的模板參數「*我需要能夠識別引用,這樣我可以跟蹤他們*「你是什麼意思? –
這與真空沒有什麼不同,它有一個函數'void f(int)'並用一個引用'int'的值來調用它。 –
這與模板無關,問題依然存在。當作爲函數參數傳遞時,變量本身始終是左值引用(無模板)。然後,根據你的函數簽名,你可以創建一個對象(成爲一個副本)(按值傳遞),或者創建一個綁定到傳入引用的左值引用。 (通過參考)。但是在調用表達式中沒有辦法指定想要傳遞參數的方式。你不能同時使用'void foo(int);'和'void foo(int&)'並調用'int i = 0; foo(i)'因爲它是不明確的 – DimG