4

私はコリルを使っています。

コマンドラインは次のとおりです。

g++ -std=c++11 -O2 main.cpp && ./a.out
clang++ -std=c++11 -O2 main.cpp && ./a.out

次のコードは、g++ では正常にコンパイルされますが、clang++ ではコンパイルされません。

    template <typename T, typename... U>
    A& operator ()(T a, U... b)
    {
        struct Inner { 
            operator decltype(T(U...)) const {
                return a(b...);
            }
        } inner;

        return *this;
    }

main.cpp:17:37: エラー: 'U' は値を参照していません

            operator decltype(T(U...)) const {

                                ^

main.cpp:13:43: 注: ここで宣言

    template <typename T, typename... U>

                                      ^

1 エラーが発生しました。

私が今得るエラーは次のとおりです。

main.cpp:18:41: error: reference to local variable 'a' declared in enclosing function 'operator()'

私のクラスは次のようになります。

template <typename R>
class A {
        R value = R();
    public:
        A() { }
        ~A() { }
        template <typename T, typename... U>
        A& operator ()(T a, U... b)
        {
            struct Inner { 
                operator decltype(std::declval<T>()(std::declval<U>()...))() const {
                    // some code here to return a(b...)
                }
            } inner;
            value += inner;
            return *this;
        }

        R val() {
            return value;
        }
};
4

1 に答える 1

7

コンパイラは正しく、値ではなく型を参照します。あなたは書く必要があります:

operator decltype(std::declval<T>()(std::declval<U>()...))() const {
// you need       ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ and ^^
    return a(b...);
}    

(最後()は、フォームの有効な変換演算子にするために必要ですoperator T() const)

aとはいえ、 andb...の内部では使用できないInnerため、例全体は意味をなさない。ユースケースが何であれ、上記は実際には機能しません.Clangがコードを受け入れるように署名を修正する方法を示すことができますが、それでも使用することはできません.


そして、あなたの更新後、それは今ではまったく別の質問です. 多分これはあなたのために働く:

template <typename R>
class A {
    R value = R();
public:
    A() { }
    ~A() { }
    template <typename T, typename... U>
    A& operator ()(T a, U... b)
    {
        struct Inner { 
            using R2 = decltype(std::declval<T>()(std::declval<U>()...));
            R2 impl(T a, U... b) const {
                return a(b...);
            }
        } inner;
        value += inner.impl(a,b...);
        return *this;
    }

    R val() {
        return value;
    }
};

Walter のコメントを参照: パラメータを渡したので、末尾の戻り値の型も使用できます。

struct Inner { 
    auto impl(T a, U... b) const -> decltype(a(b...)) {
        return a(b...);
    }
} inner;

またはC++ 14では、使用できます

struct Inner { 
    auto impl(T a, U... b) const {
        return a(b...);
    }
} inner;
于 2013-11-05T11:32:31.520 に答える