2017-03-26 13 views
1

非テンプレートクラスのテンプレートコンストラクタの明示的なインスタンスは、私の公共のヘッダは、(作業中)のようなものであるC++私はPIMPLイディオムを使用する分数クラス++ Cに取り組んでいます

Fraction.h 

コード:

#pragma once 

#include <memory> 
#include <string> 

class Fraction 
{ 
public: 
    Fraction(); 
    ~Fraction(); 

    template <typename N> 
    Fraction(N numerator, bool normalize = true); 
    template <typename N, typename D> 
    Fraction(N numerator, D denominator, bool normalize = true); 

    Fraction(Fraction&&); 
    Fraction& operator=(Fraction&&); 

    template <typename T> 
    bool operator==(T const & other); 
    template <typename T> 
    bool operator!=(T const & other); 

    std::string representation(); 

private: 
    class impl; 
    std::unique_ptr<impl> pimpl; 
}; 

私は(例えば、比較演算子オーバーロードを)メンバーの明示的なインスタンスを使用して、私のcppファイルに正しい専門を持つことができます

Fraction.cpp 

部分コード

template <typename T> 
bool Fraction::operator==(const T& other) 
{ 
    return pimpl->operator==(other); 
} 

template bool Fraction::operator==<int>(int const &); 
template bool Fraction::operator==<float>(float const &); 
template bool Fraction::operator==<double>(double const &); 
template bool Fraction::operator==<Fraction>(Fraction const &); 

しかし、私は、コンストラクタと同じことをしたいとき、私はいくつかのVS2015のコンパイラエラーがあります。

template <typename N, typename D> 
Fraction::Fraction(N num, D den, bool norm) 
    : pimpl{ std::make_unique<impl<N,D>>(num, den, norm) } 
{} 

template Fraction::Fraction<int, int>(int, int, bool); 

私は(フランス語で)エラーを構築し得る:

C2143 erreur de syntaxe : absence de ';' avant '<' fraction.cpp [156] 
C2059 erreur de syntaxe : '<'      fraction.cpp [156] 

fraction.cppライン156は、

template Fraction::Fraction<int, int>(int, int, bool); 

英語のエラー(約。翻訳):

C2143 syntax error : absence of ';' before '<' 
C2059 syntax error : '<' 

明示的なインスタンス化のいくつかのバリエーションをテストしましたが、解決策が見つかりません。私はこれが標準によって許可されていることを望みますか?


EDIT:、ここで

class Fraction::impl 
{ 
public: 
    Fraction::impl() 
     : _num (0) 
     , _den (1) 
    {} 

    ... 

    template <typename N, typename D> 
    Fraction::impl(N numerator, D denominator, bool normalize = true) 
    { 
     // TODO 
    } 

    ... 
}; 

の必要明示的な特殊化を:サムVarshavchikのコメントに答えるために、CPPのクラスは次の形式で分数クラスのプライベートな実装を統合していませんテンプレートは.hppクラスのスタイルであるためです。


SOLUTION(あるためそれほど明白(Constructorに感謝)溶液)だけ

template <typename N, typename D> 
Fraction::Fraction(N num, D den, bool norm) 
    : pimpl{ std::make_unique<impl>(num, den, norm) } 
{} 

template Fraction::Fraction(int, int, bool); 

  • impl<N,D>implで交換してください。
  • テンプレートの明示的なインスタンス化で<int, int>を削除します。

    class impl; 
    

    参照してください:

答えて

1

C++でテンプレートcontructorsの明示的なインスタンス化のために、このような構文はありません。

template Fraction::Fraction<int, int>(int, int, bool); 
          ^^^^^^^^^^ 

あなたが代わりに次の簡単な構文を使用する必要があります。

template Fraction::Fraction(int, int, bool); 
0
impl<N,D> 

implがテンプレートではない、クラスですか?これは宣言されたクラスです。これはテンプレートではなく、あなたのコンパイラは2つのテンプレートパラメータNDでインスタンス化されなければならないテンプレートであることを今に伝えようとしているという正当な理由で動揺します。

コードの意図が不明なため、適切な操作方法は明白ではありません。しかし、あなたの未来にある別の問題も明らかです:あなたがコンパイルエラーを打ち消すと、あなたはしようとしているように、templates can only be implemented in header filesファイルで、.cppファイルではないので、すぐにリンク障害を見つけます。行う。少なくともいくつかの追加作業は必要ありません。

+2

を「少なくともなく、いくつかの追加的な作業をせず」ここで追加の作業はすでに行われています。 –

+0

@Sam Varshavchik - あなたの答えをありがとう。私はFractionクラスがpimplのイディオムであると言います。 cppでは、プライベート実装は完全に満たされています。私は数分で私の質問に追加の情報を追加します。 –

関連する問題