【问题标题】:Removing const-ness from a type inside template function从模板函数内的类型中删除 const-ness
【发布时间】:2011-05-25 14:16:36
【问题描述】:
void foo (void *p); // library function; can't edit

template<typename T>
void Remove (T *p)
{
  // main code
  foo(p); // Can we remove const ness of T here ?
}

我有多个函数如Remove(),也可以用const T*调用,与foo(void*)不匹配。如果不重载/专门化Remove(),我可以删除T*constness 吗? ... 用法:

const int *p;
Remove(p); // error related to `foo()`

【问题讨论】:

  • @Kristopher,谢谢。我从那里得到了答案。还有如何实现boost 中的std::remove_cast 的想法。
  • @All,感谢您的回复。最后我最终使用了最简单的解决方案,foo((void*)p); 一开始我并没有想到。

标签: c++ templates constants


【解决方案1】:

如果你真的需要它,可以使用 boost/C++0x 元函数:

template<typename T>
void Remove (T *p)
{
    foo( const_cast< typename std::remove_const<T>::type *> (p) );
}

测试:https://ideone.com/L6urU

【讨论】:

  • std::remove_const&lt;T&gt; 的实现方式在@Kristopher 给出的链接中发布
【解决方案2】:

怎么样:

template <typename T>
struct nonconst {
    static T& value(T& value) { return value; }
};

template <typename T>
struct nonconst<T const> {
    static T& value(T const& value) { return const_cast<T&>(value); }
};

如下使用:

template<typename T>
void Remove (T* p) {
    foo(&nonconst<T>::value(*p));
}

(或者为(非)const指针进一步专门化模板。)

【讨论】:

    【解决方案3】:

    这将有效地获取一个指向常量对象的指针,并删除常量,从而使其 (foo) 能够改变对象。这将与实际暴露的接口不一致,这意味着它在任何类型上都同样(并且可以预期)工作。

    不仅如此,它还允许您使用实际 const 对象的地址调用它,这将是未定义的行为。

    相反,如果绝对需要(并保证对象不是 const),您应该在调用模板函数之前删除 const 性,以便它按预期工作(而不是改变 const 类型)。

    const A *p;
    Remove(const_cast<A*>(p)); // error for `foo()`
    

    【讨论】:

    • 同意,但这看起来很难看,必须在多个地方进行编辑。假设,我只传递可修改的const T*(这不会导致任何 UB)。
    • @iammilind 你未来的维护者会感谢你的丑陋,因为它很容易追踪,而不是“我在哪里不小心做了错误的事情,并且没有问我就神奇地抛弃了 constness” .
    • 如果是“可修改的 const T*”,为什么要声明为 const?我同意 Mark B 的观点,这看起来像是在为以后的麻烦做准备。
    【解决方案4】:

    您也可以先将static_cast 发送至const void *,然后将const_cast 发送至void *

    template<typename T>
    void Remove (T *p)
    {
        foo(const_cast<void*> (static_cast <const void*> (p)));
    }
    

    确实很丑。

    【讨论】:

      猜你喜欢
      • 2013-02-27
      • 2017-12-30
      • 1970-01-01
      • 2011-04-10
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 2011-06-08
      • 1970-01-01
      相关资源
      最近更新 更多