4

我正在使用coliru

命令行是:

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

也就是说,你不能使用aand b...inside of 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 回答