2016-02-26 72 views
2

我想部分專用於我自己的類TestHandlestd::hash結構,並且此類使用不透明指針成語進行分解。所以我正在努力爲impl提供專門的std::hash專業。但我遇到模板問題。部分專用模板的不完整聲明

有人能幫我理解爲什麼會發生這種情況嗎?我附上了所有必要的代碼。

TestHandle.h

#pragma once 
#include <memory> 

class TestHandle { 
public: 
    TestHandle(); 

    void print(); 

    class Impl; 
    std::unique_ptr<Impl> implementation; 
}; 

TestHandle.cpp

#include "TestHandle.h" 
#include "Impl.h" 
#include <iostream> 
using std::cout; 
using std::endl; 

TestHandle::TestHandle() : implementation{new TestHandle::Impl} { } 

void TestHandle::print() { 
    this->implementation->print(); 
    cout << "Hash of this->implementation is " 
     << std::hash<TestHandle::Impl>()(*this->implementation) << endl; 
} 

Impl.h

#pragma once 
#include "TestHandle.h" 
#include <functional> 

class TestHandle::Impl { 
public: 

    void print(); 
    int inner_integer; 
}; 

namespace std { 
    template <> struct std::hash<TestHandle::Impl>; 
} 

Impl.cpp

#include "TestHandle.h" 
#include "Impl.h" 
#include <iostream> 
using std::cout; 
using std::endl; 
#include <functional> 

namespace std { 
    template <> struct hash <TestHandle::Impl> { 
     size_t operator() (const TestHandle::Impl& implementation) { 
      return std::hash<int>()(implementation.inner_integer); 
     } 
    }; 
} 

void TestHandle::Impl::print() { 
    cout << "Printing from impl" << endl; 
} 

我用下面的命令

g++ -std=c++14 -c Impl.cpp TestHandle.cpp 

編譯和正在以下錯誤

TestHandle.cpp:11:12: error: invalid use of incomplete type 'std::hash<TestHandle::Impl>' 
<< std::hash<TestHandle::Impl>()(*this->implementation) << endl; 
+0

在嘗試特殊的'std :: hash' iirc之前,您應該包含'',這是主模板定義的位置 –

+0

謝謝!我將更新我的文章 – Curious

+0

另一個問題是,模板在使用它的其中一個編譯單元中不可見。 'TestHandle.cpp'需要看到實現,但是實現在'impl.cpp'中。因此,您應該將實現移至標題。 –

回答

3
template <> struct std::hash<TestHandle::Impl>; 

只是向前聲明專業化。它不必實現原始模板的所有方法(或任何)。編譯器不知道operator()

您將需要定義struct(代替聲明);

template <> struct hash <TestHandle::Impl> { 
     size_t operator() (const TestHandle::Impl& implementation) const noexcept; 
    }; 

附註:您還需要提供<functional>(原上市代碼丟失)主模板(通過包含)。

+0

我在Impl.cpp中實現了.. – Curious

+0

這應該沒問題,但定義需要可見。 – Niall

+0

我該如何去做呢?如果我有一個函數聲明和定義這工作正常...我想保持與模塊分開的實現 – Curious