0

一見、すべてが正しいように見えますが、このコードはコンパイルされません。ただし、基本クラスの戻り型をに変更するdouble *と、コンパイルされます。コンパイラがテンプレートタイプ「T」を有効なリターンタイプとして認識しない方法/理由を誰かが説明できますか?

基本クラス:

01 template <typename T>
02 class DefaultValueFunctorBase {
03   public:
04     virtual const T operator() (void) const = 0;
05 };

サブクラス:

01 class DblPtrDft : public DefaultValueFunctorBase<double *> {
02   public:
03     DblPtrDft (double default_value_)
04     : DefaultValueFunctorBase<double *>(),
05       _default_value(default_value_),
06       _default_value_ptr(&_default_value)
07     {}
08 
09     const double * operator() (void) const { return _default_value_ptr; }
10 
11   private:
12     const double *_default_value_ptr;
13     const double _default_value;
14 };

エラー:

DblPtrDft.h:09:エラー:'virtual const double * DblPtrDft :: operator()()const'に指定された競合するリターンタイプ'DefaultValueFunctorBase.h:04:エラー:オーバーライド' const T DefaultValueFunctorBase :: operator()()const [ T = double*]'</p>の場合

4

2 に答える 2

4

問題は、それconst Tをとして読み取る必要があることです。これにより、修飾子がに適用されるT constことが明確になります。したがって、テンプレートのインスタンス化でを置き換えると、基本クラスの呼び出し演算子の戻り型として取得されるのはです。constTTdouble*double* const

const double*これは、派生クラスの呼び出し演算子(つまり、と同等)にある戻り型とは異なりますdouble const*。スーパークラスでは、定数ポインタを。に返しますdouble。サブクラスでは、定数への非定数ポインタを返しますdouble

アプリケーションを修正する1つの方法は、次のとおりです。

template<typename T>
class DefaultValueFunctorBase
{
    public:
        // Do not return T const here: the top-level const is useless anyway
        virtual T operator() (void) const = 0;
};

// Instantiate your base class template with double const* rather than double*
class DblPtrDft : public DefaultValueFunctorBase<double const*>
{
public:
    DblPtrDft (double default_value_)
    : DefaultValueFunctorBase<double const*>(), // Same change here of course...
    _default_value(default_value_),
    _default_value_ptr(&_default_value)
    {}

    // Return a double const*, consistently with the instantiated template...
    double const* operator() (void) const { return _default_value_ptr; }

private:
    double const*_default_value_ptr;
    double const _default_value;
};
于 2013-02-19T02:02:55.010 に答える
1

オーバーライドされた関数はを返しますconst double *が、仮想関数はT = double *、実際にはの戻り型を持っていdouble * constます。

于 2013-02-19T01:32:18.783 に答える