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