【发布时间】:2015-03-14 14:41:03
【问题描述】:
在以下代码中:
#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。我希望你是对的。然后找出 main() 中正确的两行将解决问题,而不必担心编译器的任何错误。
-
完美转发错误:一转发双扣。我认为其中一种用途是不可推论的。
-
@Yakk。也许吧,但我把完美的转发只是为了完整性。当我删除完美转发时,我仍然得到完全相同的编译错误。
-
删除完美转发 -- 取值
const&或值。方法指针的块推导(使用常用技术)。显式传递类类型。
标签: c++ templates c++11 variadic-templates variadic