【问题标题】:Template deduction from pointer to base-class member从指向基类成员的指针的模板推导
【发布时间】:2014-02-28 05:41:10
【问题描述】:

我不知道我做错了什么。从指针到基类成员的模板推导中的问题 - &DerivedClass::BaseClassMemeber。

完整示例:

#include <vcl.h>
#include <tchar.h>

struct Base
{
   int BaseClassMember;
};

struct Derived : public Base
{
};

template<class T1, class T2>
void Test(T1& Param1, T2 T1::* Param2)
{
}

int _tmain()
{
   Derived inst;
   // Compile error E2285 Could not find a match for 'Test<T1,T2>(B,int A::*) - BCC32
   // Error 1 error C2782: 'void Test(T1 &,T2 T1::* )' : template parameter 'T1' is   ambiguous - MS VS8
   Test(inst, &Derived::BaseClassMember);

   // Works great
   Test<Derived>(inst, &Derived::BaseClassMember);
   return 0;
 }

我可以找到几种解决方法,例如额外的 Test 函数重载,多了一个模板参数 static_cast,隐式偏特化 (Test)。

但我对为什么编译器不能使用 &DerivedClass::BaseClassMemeber 中明确指定的类感兴趣。就是那个问题。如果你有更优雅的问题解决方案,欢迎。

【问题讨论】:

  • 您可能还会发现您在 clang 3.3 上的“效果很好”很有趣。 Test&lt;Base&gt;,然而,确实
  • 好的,这排除了一种解决方法,但问题出在哪里?
  • 对于使用另一个模板参数的解决方法,我会说将其实现为 template&lt;class T1, class T2, class T3&gt; typename std::enable_if&lt;std::is_convertible&lt;T2 T3::*, T2 T1::*&gt;::value, void&gt;::type Test(T1&amp; Param1, T2 T3::* Param2),或者如果 C++11 是一个选项,template&lt;class T1, class T2, class T3&gt; auto Test(T1&amp; Param1, T2 T3::* Param2) -&gt; decltype(Param1.*Param2, void())。如果您添加额外的 Test 重载,它们将帮助您,您希望重载解析忽略对此特定 Test (Test(inst, &amp;Unrelated::ClassMember);) 的无效尝试调用。
  • 不知道 std::enable_if,谢谢。不幸的是,c++11 不是一个选项。

标签: c++ templates pointer-to-member template-argument-deduction


【解决方案1】:

&amp;Derived::BaseClassMember 的类型为 int Base::*,而不是 int Derived::*。标准:

一元&amp; 运算符的结果是指向其操作数的指针。操作数应为左值或qualified-id。如果操作数是一个qualified-id,命名某个类C 的非静态成员m 类型为T,则结果类型为“指向类C 的成员的指针”键入T”并且是一个prvalue,指定C::m。 [...跳过...] [示例:

struct A { int i; };
struct B : A { };
... &B::i ...             // has type int A::*i

——结束示例]

如果你需要这种类型,你必须将值转换为int Derived::*

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-05
  • 1970-01-01
相关资源
最近更新 更多