Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Adding a new CS

...

The interface for std::plus requires that both arguments to the function call operator and the return type are of the same type. Because the attempted specialization in the noncompliant code example results in undefined behavior, this compliant solution defines a new std::binary_function derivative that can add a std::string to a MyString object without requiring modification of the namespace std.

Code Block
bgColor#ccccff
langcpp
#include <functional>
#include <iostream>
#include <string>

class MyString {
  std::string data;
  
public:
  MyString(const std::string &data) : data(data) {}
  
  const std::string &get_data() const { return data; }
};

struct my_plus : std::binary_function<std::string, MyString, std::string> {
  std::string operator()(const std::string &lhs, const MyString &rhs) const {
    return lhs + rhs.get_data();
  }
};

void f() {
  std::string s1("My String");
  MyString s2(" + Your String");
  my_plus p;
  
  std::cout << p(s1, s2) << std::endl;
}

Compliant Solution

In this compliant solution, a specialization of std::plus is added to the std namespace, but the specialization depends on a user-defined type and meets the Standard Template Library requirements for the original template, and so it complies with this rule. However, because MyString can be constructed from std::string, this compliant solution involves invoking a converting constructor whereas the previous compliant solution does not.

Code Block
bgColor#ccccff
langcpp
#include <functional>
#include <iostream>
#include <string>
 
class MyString {
  std::string data;
   
public:
  MyString(const std::string &data) : data(data) {}
   
  const std::string &get_data() const { return data; }
};
 
namespace std {
template <>
struct plus<MyString> {
  MyString operator()(const MyString &lhs, const MyString &rhs) const {
    return lhs.get_data() + rhs.get_data();
  }
};
}
 
void f() {
  std::string s1("My String");
  MyString s2(" + Your String");
  std::plus<MyString> p;
   
  std::cout << p(s1, s2).get_data() << std::endl;
}

Risk Assessment

...