c++ - 如何更喜欢调用 const 成员函数并回退到非常量版本?

标签 c++ templates member-functions

考虑一个类 Bar在库的两个版本中:

/// v1
class Bar
{
  void get_drink()
  {
    std::cout << "non-const get_drink() called" << std::endl;
  }
};


/// v2
class Bar
{
  void get_drink()
  {
    std::cout << "non-const get_drink() called" << std::endl;
  }

  void get_drink() const
  {
    std::cout << "const get_drink() called" << std::endl;
  }
};
在客户端代码上,我们拥有一个 Bar反对并愿意 get_drink .我希望能够更喜欢调用 get_drink() 的 const 版本如果它可用(使用 v2 库时)并回退到非常量版本(使用 v1 库时)。那是:
Bar bar;

bar.get_drink(); // this does not call the const version of v2

static_cast<const Bar&>(bar).get_drink(); // this does not compile against v1 library
不幸的是,该库没有版本控制,没有其他方法可以区分这两个版本。
我认为必须使用一些模板魔法。所以问题是如何?

最佳答案

这似乎有效:

#include <type_traits>
#include <iostream>

template<typename T, typename=void>
struct find_a_drink {

    void operator()(T &t) const
    {
        t.get_drink();
    }
};

template<typename T>
struct find_a_drink<T,
            std::void_t<decltype( std::declval<const T &>()
                      .get_drink())>
            > {

    void operator()(T &t) const
    {
        static_cast<const T &>(t).get_drink();
    }
};

template<typename T>
void drink_from(T &&t)
{
    find_a_drink<std::remove_reference_t<T>>{}(t);
}

/// v1
class Bar1
{
public:
  void get_drink()
  {
    std::cout << "non-const get_drink() called (Bar1)" << std::endl;
  }
};

class Bar2
{
public:
  void get_drink()
  {
    std::cout << "non-const get_drink() called (Bar2)" << std::endl;
  }

  void get_drink() const
  {
    std::cout << "const get_drink() called (Bar2)" << std::endl;
  }
};

int main()
{
    Bar1 b1;
    Bar2 b2;

    drink_from(b1);
    drink_from(b2);
    return 0;
}
结果:
non-const get_drink() called (Bar1)
const get_drink() called (Bar2)

关于c++ - 如何更喜欢调用 const 成员函数并回退到非常量版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69263122/

相关文章:

c++ - 将宏定义的函数转换为 C++ 中的模板

c++ - 转发成员函数的 cv-ref-qualifier

c++ - openssl 加密库 - base64 转换

c++ - 语法平衡问题

c++ - 流操纵器的模板类型推导

c++ - 使用基类的派生类中定义的类型

c++ - 继承通用成员函数

c++ - 如何找出使用 gcc 时实际应用了哪些优化?

c++ - 在哪里放置要与 Windows 用户的桌面设置一起漫游的用户数据文件?

.net - WPF - 没有容器的数据模板,项目作为网格中的行?