在以下代碼:與局部參數包可變參數的輔助函數
#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