有一个库提供了一个通用函数和一些要使用的实现:
#include <iostream>
namespace lib {
struct Impl1 {};
struct Impl2 {};
void process(Impl1) { std::cout << 1; }
void process(Impl2) { std::cout << 2; }
template<typename T> void generalize(T t) { process(t); }
}
Run Code Online (Sandbox Code Playgroud)
我想通过外部代码扩展它。以下是 C++ 允许这样做的方式:
#include <lib.h> // the previous snippet
namespace client {
struct Impl3 {};
void process(Impl3) { std::cout << 3; }
}
int main() { // test
lib::generalize(client::Impl3{}); // it couts 3
}
Run Code Online (Sandbox Code Playgroud)
注意:lib的代码对 的一无所知,client并且不执行动态调度。如何在我的 Rust 代码中实现相同的目标?(如果我不能,是否有类似计划?)
overloading generic-programming open-closed-principle rust argument-dependent-lookup
使用类型特征,我可以执行以下操作:
template<typename Rect> Rect& move(Rect& rc, size_type<Rect> delta)
{
rc.left += delta.width;
rc.right += delta.width;
rc.top += delta.height;
rc.bottom += delta.height;
return rc;
}
template<typename Rect> Rect& move(Rect& rc, point_type<Rect> to)
{
int w = w(rc);
int h = h(rc);
rc.left = to.x;
rc.top = to.y;
rc.right = rc.left + w;
rc.bottom = rc.top + h;
return rc;
}
Run Code Online (Sandbox Code Playgroud)
但是如何在不更改函数名称的情况下允许传递任何大小和点类型?显然我不能这样做:
template<typename Rect, typename Size> Rect& move(Rect& rc, Size delta);
template<typename Rect, typename Point> Rect& move(Rect& rc, Point to); …Run Code Online (Sandbox Code Playgroud) c++ templates overloading metaprogramming template-meta-programming
我想reverse(BidirectionalIterator first, BidirectionalIterator last)从<algorithm>我的函数内部的头文件中调用一个函数,它的名字也是reverse(int).
代码:
#include<iostream>
#include<algorithm>
using namespace std;
class Solution{
public:
int reverse(int x){
string num = to_string(x);
reverse(num.begin(), num.end());
}
};
Run Code Online (Sandbox Code Playgroud)
我认为它会根据传递的参数自动调用适当的函数,就像函数重载一样。但是,它没有。
我试过:
namespace algo{
#include<algorithm>
}
Run Code Online (Sandbox Code Playgroud)
但它给出了很多错误。
所以问题来了。我有一个 B 类,其中我重载了 << 运算符,还有一个 A 类,其中 << 运算符也重载了。但是,类 B 中的 << 重载似乎在类 A 中的 << 重载中不起作用。它只是返回 b 的地址,就好像类 B 中的 << 重载不存在一样。
任何帮助将不胜感激
#pragma once
#include <ostream>
using namespace std;
class B {
public:
B(int x) {
this->x = x;
}
friend ostream& operator<<(ostream& os, B& b)
{
os << "this is B " << b.x;
return os;
}
private:
int x;
};
Run Code Online (Sandbox Code Playgroud)
#pragma once
#include <ostream>
#include "B.h"
using namespace std;
class A {
public:
A(B* b) { …Run Code Online (Sandbox Code Playgroud) 我想创建一个类型别名array_t。它应该适用于有界和无界数组。我可以像这样为每个案例分别声明它:
// Type of an unbounded array of `T`
template <typename T>
using array_t = T[];
// Type of an array of `T` of size `Size`
template <typename T, size_t Size>
using array_t = T[Size];
Run Code Online (Sandbox Code Playgroud)
问题是两者不能同时声明。我认为解决方案可能是使用某种模板专业化,但我不确定在这种情况下如何使用它。
我需要区分(重载)两个函数——一个接受一个const char*参数,另一个接受至少两个参数——一个const char*后跟一个或多个参数。即基本上:
void f(const char *str);
void f(const char *format, ...)
Run Code Online (Sandbox Code Playgroud)
我想要第一个版本被调用,f("hello")第二个版本被调用f("hello %d", 10)。上述重载将不起作用,因为编译器发现f("hello")歧义。
所以我试过这个:
void f(const char *str);
template<typename T>
void f(const char *str, T tt, ...);
Run Code Online (Sandbox Code Playgroud)
这使得重载解析正常工作。但我最终遇到了另一个问题。第二个函数应该转发 printf 样式使用的参数。所以我有类似的东西:
template <typename T>
void f ( const char *format, T tt, ... )
{
(T)tt;
va_list varlist;
va_start(varlist, format);
vprintf(format, varlist);
va_end(varlist);
}
Run Code Online (Sandbox Code Playgroud)
现在第二个参数tt不再是变量参数列表的一部分,并且调用va_start()withformat 似乎不起作用。
有什么办法可以实现我想要的吗?
我有一个Expression存储代数术语的类。我希望它拥有的公共接口是这样的:
expr.add({1}) // add term "x1". (error: code adds constant 1)
expr.add({0,1}) // add term "x0 * x1".
expr.add({0},2) // add term "2 * x0"
expr.add(2) // add constant 2
Run Code Online (Sandbox Code Playgroud)
但是我遇到的问题expr.add({1})是被解释为添加整数 1,而不是添加包含 1 的向量。有什么办法可以修复下面的实现以允许上面的接口?(或者至少抓住它?)因为打字expr.add(std::vector({1}))太冗长了。
#include <tuple>
#include <vector>
#include <unordered_set>
#include <iostream>
class Expression
{
using var_t = unsigned int;
using term_t = std::pair<int, std::vector<var_t>>;
std::vector<term_t> terms;
public:
void add(const std::vector<var_t>& vars, int coeff=1)
{
std::cout << "Adding a term" << std::endl;
terms.push_back(std::make_pair(coeff, vars)); …Run Code Online (Sandbox Code Playgroud) 我想重载此结构的索引运算符:
struct Ram<'a> {
ram: &'a mut [u8]
}
impl<'a> Ram<'a> {
pub fn new( bytes: &mut[u8]) -> Ram {
Ram {
ram: bytes
}
}
}
Run Code Online (Sandbox Code Playgroud)
...基本上是字节数组上的“控制器”。我这样做是因为我想将它重用于不同大小的字节数组。我知道生命周期在这里是为了确保“ram”引用在整个执行过程中都是有效的。这是我当前的索引代码:
use std::ops::{Index};
impl<'a> Index<usize> for Ram<'a> {
type Output = u8;
fn index(&self, i: usize) -> &'a u8 {
&self.ram[i]
}
}
Run Code Online (Sandbox Code Playgroud)
这不编译。Rust 说有一个匿名生命周期定义与 'a 在 index(...) 定义中冲突:“错误[E0495]:由于需求冲突,无法推断函数调用中生命周期参数的适当生命周期”。
我应该如何实现这一点?还是我对一生的假设完全错误?谢谢。
我正在学习 C++,但我对重载运算符和函数的真正含义感到困惑。
在我使用过的本地文献中,有一个重载函数的翻译,其中“负载”是名词,而不是动词——所以它的意思是“过度的负载或负担”,尽管在这种情况下,正如我所理解的,从这个意义上说,没有什么是“超载”的(例如类似于电路超载)。
如果我们将“加载”视为动词,那么它意味着函数在现有定义上“再次加载一次”。
我在正确的道路上,在编程的情况下对“重载”的正确解释是什么?
我正在尝试使用类型特征为特定函数提供几个重载,以便在调用所述函数时不必指定模板参数,并且它可以用于任何数据类型和不同类型的容器:
#include <type_traits>
#include <vector>
#include <initializer_list>
template< typename T, typename = std::enable_if< std::is_arithmetic< T >::value > >
bool myFunction(const std::vector< T >& data) {
// ...
return true;
}
template < typename T, typename = std::enable_if< !std::is_arithmetic< T >::value >, typename = void >
bool myFunction(const std::vector< T >& data) {
// ...
return true;
}
template< typename T >
bool myFunction(const std::initializer_list< T >& data) {
return myFunction< T >(std::vector< T >(data));
}
int main(int argc, char const …Run Code Online (Sandbox Code Playgroud) overloading ×10
c++ ×8
templates ×3
function ×2
rust ×2
indexing ×1
lifetime ×1
namespaces ×1
sfinae ×1
terminology ×1
type-alias ×1
type-traits ×1
using ×1