簡體   English   中英

為什么這樣編譯,模板推導應該失敗?

[英]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.ref],[dcl.init.ref]),則在進行任何進一步分析之前,將類型調整為T。 表達式指定由引用表示的對象或功能,並且表達式取決於表達式是左值還是x值。 [注意:在引用的生存期開始之前或結束之后,行為是不確定的(請參閱[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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM