'U'不是指一个值

时间:2013-11-05 11:27:56

标签: c++ c++11 g++ clang++

我正在使用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;
        }
};

1 个答案:

答案 0 :(得分:6)

编译器是对的,它指的是类型,而不是值。你需要写:

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

(需要最后()才能使其成为operator T() const形式的有效转换运算符

也就是说,您无法在a内使用b...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;