首页 > Coding > C++: 函数返回值可以重载吗

C++: 函数返回值可以重载吗

2024年3月3日 发表评论 阅读评论

函数重载(Function Overloading)允许在同一个作用域内定义多个功能类似但参数不同的函数。这些函数可以有相同的名字,但必须有不同的参数列表(参数的数量、类型或顺序不同)。编译器通过参数列表来决定调用哪个函数。

大部分语言并不支持返回值类型的重载。包括C++。

// OK
std::string to_string(int i);
std::string to_string(bool b);

std::string si = to_string(42);
std::string sb = to_string(true);

// ERROR
int from_string(std::string_view s);
bool from_string(std::string_view s);

int i = from_string("42");
bool b = from_string("false");

C++ 11 的一个新特性,使我们可以实现一个 接近 函数返回值重载的功能。即 [自定义转换函数][https://en.cppreference.com/w/cpp/language/cast_operator] 。来看下面的例子:

struct to_string_t
{
    std::string_view s;  //string_view from c++17

    operator int() const; 
    operator bool() const;
};

int i = to_string_t{"42"};  //  operator int() const; 
bool b = to_string_t{"true"};  //  operator bool() const;

需要注意,编译器需要知道转换的目标类型。如 auto i = to_string_t{"42"} ,编译器不知道应该调用哪个重载。
让我们回到开始:如何将 to_string_t 作为返回值,似乎就可以完成 函数返回值重载 的功能:

to_string_t from_string(std::string_view str){
  return to_string_t{str};
};

int i = from_string("42");
auto b = bool(from_string("42"));

void foo(int i, bool b){}
foo(from_string("42"), from_string("true"));

std::vector<int> v;
v.emplace_back(from_string("42"));

上面的代码中, 我们给出了 bool int 两种转换。如果想要它变得更灵活, 可以使用模板偏特化来实现

template<typename T>
struct always_false : std::false_type {};

template<typename T>
struct to_string_impl{
  static_assert(always_false<T>(), "No to_string_impl for this type");
};

struct to_string_t{
  std::string_view s;

  template<typename T>
  operator T() const {
    return to_string_impl<T>::from_string(s);
  }
};

template<>
struct to_string_impl<int>{
  static int from_string(std::string_view s){
    return std::stoi(std::string(s));
  }
};

to_string_t from_string(std::string_view s){return to_string_t{s};}

在实际使用中, 我们可以根据需求对 to_string_impl<T> 进行偏特化实现。对于未实现的类型则会在编译时抛出 Error.

int i = from_string("42");  //OK
bool b = from_string("true"); //ERROR error: static_assert failed due to requirement 'always_false<bool>()' "No to_string_impl for this type"

任何使用 from_string 的用户都可以根据需求实现或扩展这个类

  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.