gpt4 book ai didi

c++ - 使用隐式转换模拟 C++ 函数模板实例化

转载 作者:行者123 更新时间:2023-11-30 04:40:08 24 4
gpt4 key购买 nike

我已经问过了two questions与我正在尝试做的事情相关(一个已解决,其中一个我将很快关闭)。我知道 C++ 模板实例化不允许任何隐式转换(例如参见 this comment ),但我想模拟它。

假设我有以下框架代码:

template <class T>
struct Base_A{
virtual void interface_func() const = 0;
};
template <class T>
struct Derived_A : public Base_A<T>{
typedef T value_type;
void interface_func() const{}
};

template <class T>
struct Base_B{
virtual void interface_func() = 0; // note: non-const
};
template <class T>
struct Derived_B : public Base_B<T>{
typedef T value_type;
void interface_func(){}
};

template <class BType>
struct Adapter : public Base_A<typename BType::value_type>{
BType &ref_B;
Adapter(BType &inst_B):ref_B(B_inst){}
void interface_func() const{} // does stuff with ref_B to simulate an A
};

template <class Should_Always_Be_Base_A>
void f(const Should_Always_Be_Base_A &arg){
// Only Base_A can be passed in by const ref
// Passing in a Base_B by const ref would not work.
}

Derived_A<int> A;
Derived_B<int> B;
f(A); // passes in A by const ref
f(B); // I want to pass in Adapter<Derived_B<int> >(B)

我希望函数 f 的模板参数始终是 Base_AAdapter 的派生类。限制arg类型的答案can be done ,但不能隐式转换为 Adapter。有什么办法吗?最终结果是我希望能够将 f 调用为 f(A)f(B),在这两种情况下我都需要了解 f 中 A 或 B 的实际派生类型(f 不能只看到对基类的引用)。

旁白:

目前,我只有 f(A) 工作,而 f(B) 实际上调用了一个执行 Adapter 构造的重载,但我还有其他函数需要N 个参数,每个参数可以是 A 或 B,所以我需要 2^N 个重载。

出于好奇,这是对我正在处理的矩阵库的应用。 Base_A 表示基本矩阵类型,Base_B 表示基本矩阵 View 类型。对于将修改矩阵参数的操作,我需要通过非常量引用传递矩阵或通过 const-ref 传递可修改的矩阵 View 。该适配器只是一个普通的矩阵到 View 适配器。因此,例如,我目前有一个类似的功能

Scale(const MatrixViewBase<T> &Mview, const T &scale_factor){
// does the actual work
}
Scale(MatrixBase<T> &M, const T &scale_factor){
Scale(Adapter<MatrixBase<T> >(M), scale_factor);
}

制作所有这些函数的 2^N 个拷贝只是为了创建所需的重载来处理 View 和非 View ,这既乏味又容易出错。事实上,这还不够好,因为我希望 Scale 能够知道 Mview 的完整派生类型,而不仅仅是基类,因为我可能会生成依赖于 Mview 的类型的实例。

编辑 1: 将所有 B 类型更改为具有非常量接口(interface)函数。这是最初的意图,对于任何混淆,我们深表歉意。

编辑 2: 有这个工作代码,仍然需要 2^N 次重载,但我可以接受它,除非有人建议如何处理它。

#include <iostream>

template <class T>
struct ReadableMatrix{
typedef T value_type;
};
template <class T>
struct WritableMatrix{
typedef T value_type;
};
template <class T>
struct WritableMatrixView{
typedef T value_type;
};

template <class T>
struct Matrix : public WritableMatrix<T>{
typedef T value_type;
typedef ReadableMatrix<T> readable_matrix;
typedef WritableMatrix<T> writable_matrix;
};

template <class T>
struct MatrixView : public WritableMatrixView<T>{
typedef T value_type;
typedef ReadableMatrix<T> readable_matrix; // not really used; needs an adapter before using
typedef WritableMatrixView<T> writable_matrix;
};

template <class T, class R>
struct IsReadableMatrix{
};
template <class T, class R>
struct IsReadableMatrix<ReadableMatrix<T>, R>{
typedef R type;
};

template <class T, class R>
struct IsWritableMatrix{
};
template <class T, class R>
struct IsWritableMatrix<WritableMatrix<T>, R>{
typedef R type;
};

template <class T, class R>
struct IsWritableMatrixView{
};
template <class T, class R>
struct IsWritableMatrixView<WritableMatrixView<T>, R>{
typedef R type;
};

template <class TA, class TB>
typename IsReadableMatrix<typename TA::readable_matrix,
typename IsWritableMatrixView<typename TB::writable_matrix,
void
>::type>::type
Copy(const TA &A, const TB &B){
std::cout << "Here" << std::endl;
}

template <class TA, class TB>
typename IsReadableMatrix<typename TA::readable_matrix,
typename IsWritableMatrix<typename TB::writable_matrix,
void
>::type>::type
Copy(const TA &A, TB &B){
std::cout << "Here2" << std::endl;
}

int main(){
Matrix<int> M, M2;
MatrixView<int> V, V2;
Copy(M, M2);
Copy(V, V2);
Copy(M, V);
Copy(V, M);
}

最佳答案

你需要你的基类成为模板吗?你能注入(inject)甚至“更多基础”的非模板类吗?如果是,您可以这样做:

struct Base_A{
virtual void interface_func() const = 0;
};

template <class T>
struct Derived_A : public Base_A{
typedef T value_type;
void interface_func() const{}
};

struct Base_B{
virtual void interface_func() const = 0;
};

template <class T>
struct Derived_B : public Base_B{
typedef T value_type;
void interface_func() const{}
};

struct Adapter
{
const Base_A* pA;
const Base_B* pB;

Adapter(const Base_B &inst_B) : pB(&inst_B), pA(0){}
Adapter(const Base_A &inst_A) : pA(&inst_A), pB(0){}
void interface_func() const
{
if( 0 != pA )
pA->interface_func();
else if( 0 != pB )
pB->interface_func();
}
};


void f(const Adapter &arg)
{
arg.interface_func(); // will call proper interface_func
}


int main()
{
Derived_A<int> A;
Derived_B<int> B;
f(A);
f(B);
}

关于c++ - 使用隐式转换模拟 C++ 函数模板实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1752063/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com