c++ - 是否可以编写一个同时接受右值和左值的模板函数

标签 c++ templates

我想为 std::vector 添加算术重载(可能不是一个好主意,但我想以此为例)。我可以如下实现它

template <typename T, typename T2> auto& operator+=(std::vector<T>& a, const std::vector<T2>& b)
{
    assert(a.size() == b.size());

    std::transform(a.begin(), a.end(), b.begin(), a.begin(), std::plus<>());
    return a;
}

template <typename T, typename T2> auto operator+(const std::vector<T>& a, 
const std::vector<T2>& b)
{
    auto a0 = a;
    return a0 += b;
}

template <typename T, typename T2> auto operator+(std::vector<T>&& a, 
const std::vector<T2>& b)
{
    auto a0 = a;
    return a0 += b;
}

为了利用 C++11 中的右值语义,我需要为 operator+ 编写两个函数。是否可以删除 operator+ 的重复代码?

最佳答案

您可以使用perfect-forwarding 并可能通过 SFINAE 进行约束,例如

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

template<typename T>
struct is_vector_addable<std::vector<T>>: std::true_type {};

template <typename T, typename T2,typename E=
std::enable_if_t< is_vector_addable<std::decay_t<T>>::value >>
auto operator+( T&& a,  const std::vector<T2>& b)
{
    auto a0 = std::forward<T>(a);
    return a0 += b;
}

Sebastian Redl 所建议,您还可以进一步限制 std::vector 具有可添加元素(在 std::transform 与 std::plus 语义的意义上,这可能会也可能不会成为你真正想要的),在 C++17 中:

template<typename T,typename T2,typename = void>
struct is_vector_addable: std::false_type {};

template<typename T,typename T2>
struct is_vector_addable<std::vector<T>,T2,std::void_t<
  decltype( std::declval<T>() = std::declval<T>() + std::declval<T2>() )
  >>: std::true_type {};

template <typename T, typename T2,typename E=std::enable_if_t< is_vector_addable<std::decay_t<T>,T2>::value >>
auto operator+( T&& a,  const std::vector<T2>& b)

关于c++ - 是否可以编写一个同时接受右值和左值的模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47408781/

相关文章:

c++ - MinGW C++ : expected primary-expression before '/' token

c++ - 错误 C2146 : syntax error : missing ';' before identifier 'ContextRecord'

c++ - 使用malloc代替new,创建对象时调用拷贝构造函数

c++ - 类 TESTDLL_LIBSHARED_EXPORT TestDLL_lib

PHP,聪明人 : Check for template in different folders

c++ - 具有模板化成员函数的类,是同一个类吗?

c++ - Visual Studio 在调试时随机启动断点

python - Django 模板迭代列表

c++ - 成员函数作为 std::function 传递给模板,绑定(bind)所有参数

wpf - 使用视觉状态管理器设置前景时出现问题