4

この質問への回答としていくつかの式テンプレートを作成しようとしていましたが、コンパイラ エラーが発生し、わかりません。私は今ではSSCCEをかなり小さくしています

template<class sub_expr>
class inherit2 : private sub_expr { //line 3
public:
    inherit2(sub_expr rhs) : sub_expr(rhs) {}
    template<class T>
    auto operator()(const T& v) const ->decltype(sub_expr::operator()(v)) //line 7
    {return sub_expr::operator()(v);}
};

class expression_parameter {
public:
    template<class T>
    const T& operator()(const T& v) const {return v;}
};

int main() {
    expression_parameter x;
    auto expr0 = x;
    int res0 = expr0(3); //line 20
    auto expr1 = inherit2<expression_parameter>(x); //line 21
    int res1 = expr1(3); //line 22
    return 0;
}

MSVC10++ でコンパイルすると、次のエラーが発生します。

f:\code\utilities\exprtemplate\exprtemplate\sscce.cpp(22): error C2893: Failed to specialize function template ''unknown-type' inherit2<sub_expr>::operator ()(const T &) const'
with
[
    sub_expr=expression_parameter
]
With the following template arguments:
'int'

GCC 4.6.3 でコンパイルすると:

sscce.cpp: In instantiation of 'inherit2<expression_parameter>':
sscce.cpp:21:47:   instantiated from here
sscce.cpp:3:7: warning: base class 'class expression_parameter' has a non-virtual destructor [-Weffc++]
sscce.cpp: In function 'int main()':
sscce.cpp:22:20: error: no match for call to '(inherit2<expression_parameter>) (int)'
sscce.cpp:3:7: note: candidate is:
sscce.cpp:7:10: note: template<class T> decltype (sub_expr:: operator()(v)) inherit2::operator()(const T&) const [with T = T, sub_expr = expression_parameter, decltype (sub_expr:: operator()(v)) = decltype (expression_parameter::operator()(v))]
sscce.cpp:20:6: warning: unused variable 'res0' [-Wunused-variable]
sscce.cpp:22:6: warning: unused variable 'res1' [-Wunused-variable]

そして最後に Clang 3.1

sscce.cpp(22,12) :  error: no matching function for call to object of type 'inherit2<expression_parameter>'
        int res1 = expr1(3);
                   ^~~~~
sscce.cpp(7,9) :  note: candidate template ignored: substitution failure [with T = int]
    auto operator()(const T& v) const ->decltype(sub_expr::operator()(v))
         ^

要約すると、間違っているように見えますdecltypeが、正しい方法がわかりません。これらのエラーの原因を特定できる人はいますか?

4

2 に答える 2

2

これは Luc の修正の補遺です。使用する:

decltype(std::declval<lhs>()( v ) * std::declval<rhs>()( v ) )

コンパイラが苦労せずに型を推測できるようにするため。

于 2012-06-15T18:38:39.003 に答える
2

GCC から得たエラーのいくつかは、あいまいなベースが含まれていることを示唆していました。つまり、(直接)ベースとしてexpression_multiply<expression_parameter, expression_parameter>持っており、それ自体がベースとして持っています。これは、 の範囲が曖昧であることを意味します(実際には.expression_parameterinherit_again<expression_parameter>expression_parameterlhs::operator()expression_multiply<expression_parameter, expression_parameter>lhsexpression_parameter

thisの戻り値の型で必要だった で、さらに修正が必要でしたoperator()。その結果、次の修正が行われました。

// Instead of inherit_again
template<int N, class sub_expr>
class base : public sub_expr {
public:
    base(sub_expr rhs): sub_expr(std::move(rhs)) {}
};

template<class lhs_given, class rhs_given>
class expression_multiply: private base<0, lhs_given>, private base<1, rhs_given> {
    typedef base<0, lhs_given> lhs;
    typedef base<1, rhs_given> rhs;
public:
    expression_multiply(lhs_given l, rhs_given r):lhs(std::move(l)), rhs(std::move(r)) {}
    template<class T>
    auto operator()(const T& v) const
    -> decltype(this->lhs::operator()(v) * this->rhs::operator()(v))
    {
        return lhs::operator()(v) * rhs::operator()(v);
    }
};

これら2つの「修正」の必要性に関して、コンパイラが修正を行っているかどうかはわかりません。

于 2012-06-15T05:11:31.977 に答える