将方法静态传播到派生类

时间:2016-08-08 08:54:45

标签: c++ c++11

template<typename T> struct Derived: T
{
  /*static*/ int foo(int x) { return T::foo(x) + 1; }
};

如果T::foo(int x)static,则Derived<T>::foo(int x)也应为static。否则Derived<T>::foo(int x)应该是非静态的。

有没有办法让编译器处理这个?

2 个答案:

答案 0 :(得分:1)

不,你不能在你提出的意义上传播static。顺便提一下,你也可以对const

提出同样的问题
int foo(int x) { return bar(x) + 1; } // Infer that foo is const because bar is

C ++说明符旨在表达关于接口的意图,即使实现发生变化,用户也可以依赖>

static int foo(x); // This method does not require an object
int foo(x) const; // This method will not modify the object

如果 - 通过模板 - 例如 - 实现可能会有所不同,您的界面必须反映最低的公分母。例如,对于const,方法必须为非const。对于static,这是您的问题,您无法声明static

请注意,这不是一个巨大的强加。即使方法为static,您也可以still call it using with object semantics。因此,在您的情况下,您将不得不使用对象语义。特别是关于你在评论中的澄清

  

如果allocator是静态的,那么容器不需要保持它的指针。所以装饰者必须保持静态。

请注意,装饰器也可以保留static,因为容器可以在任何情况下保持指针,并通过对象表示法调用它们,无论它们是什么const岬。

答案 1 :(得分:0)

使用以下构造:

static_assert(std::is_same<decltype(&Derived::foo), decltype(&T::foo)>::value or
              (std::is_member_function_pointer<decltype(&Derived::foo)>::value and 
               std::is_member_function_pointer<decltype(&T::foo)>::value), 
              "Derived::foo & T::foo are not having same static-ness");

我已经使用我的g ++进行了快速测试,效果很好。

它做什么

  1. 采用两种方法的地址,如果它们具有可比性 他们必须是static。这意味着方法签名是 预期是相同的(如你的例子所暗示的那样)。
  2. 如果(1)失败,则检查foo是否都是函数指针 他们各自的班级类型。这里没有严格的类型,但你可以强加一些元编程。离开你。
  3. 如果上述两种方法都失败,则编译器会出错。此static_assert可以放在class Derived

    备注 :( 1)如果Derived::foostatic&amp; T::foo不是那么,它会给出错误。 (2)or&amp; and是C ++的官方关键字。如果MSVC等某些编译器不支持,请使用||&amp;分别为&&