在以下代码:与局部参数包可变参数的辅助函数
#include <iostream>
struct Base {
virtual ~Base() = default;
template <typename T, typename... Args> void helper (void (T::*)(Args..., int), Args...);
void bar (int n) {std::cout << "bar " << n << std::endl;}
};
struct Derived : Base {
void baz (double d, int n) {std::cout << "baz " << d << ' ' << n << std::endl;}
};
template <typename T, typename... Args>
void Base::helper (void (T::*f)(Args..., int), Args... args) {
// A bunch on lines here (hence the motivation for the helper function)
for (int n = 0; n < 5; n++)
(dynamic_cast<T*>(this)->*f)(args..., n);
// ...
}
int main() {
Base b;
Derived d;
b.helper(&Base::bar); // GCC 4.8.1 will accept this, Visual Studio 2013 won't.
d.helper<Derived, double>(&Derived::baz, 3.14); // Visual Studio 2013 will accept this, GCC 4.8.1 won't
}
我不能获得任一GCC4.8.1或VS2013编译上述两条线。他们将只编译一个而不编译另一个(并且他们不同意哪一行是正确和不正确的)。错误消息指出两个编译器都失败了模板扣除。那么究竟是什么错误?我已经把所有的模板参数放在最后一行(我认为可以推导出来),但它仍然不能由GCC推导出来,尽管VS可以。然而,当我放置模板参数时,VS不能推导出b.foo(&Base::bar);
行的模板参数,但GCC可以推导出它们而没有任何模板参数。完全在这里困惑。这两个编译器都在这里窃听?程序员的任何可能的修复?
东西告诉我,两条线都是无效的,但我不能拿出一个理由为什么呢。 – Barry
@Barry。我希望你是对的。然后找出main()中正确的两行就可以解决问题,而不用担心编译器会有任何问题。 – prestokeys
你正在得到完美的转发错误:一个转发双重扣除。我认为一种用途是不可诱导的。 – Yakk