Important: This question is getting quite long,if this is the first time you’re reading this I suggest you start near the bottom as the solution is there in a round about way,but the code is a bit smelly.

阅读tutorial on templates之后,我能够更改现有类以支持泛型类型.但是,许多对象已经依赖于此,所以我正在寻找一种使方法通用而不是整个类的方法.

我尝试了以下内容,但看起来不支持此行为.

// foobar1.h
// Don't want the entire class to be generic.
//template<class T>
class FooBar1
{
public:
    template<class T> T Foo();
}

// foobar2.h
class FooBar2 : public FooBar1
{
}

// foobar1.cpp
template<class T>
T FooBar1::Foo()
{
    return something;
}

// test.cpp
FooBar1 fb1;
FooBar2 fb2 = fb1.Foo<FooBar2>();

这应该不起作用,还是我在其他地方遇到的一个错误?

undefined reference to FooBar2 Foo<FooBar2>()

为了实现我想要实现的目标,我在C#中如何做到这一点……

public class FooBar1
{
    public T Foo<T>()
        where T : FooBar1
    {
        return something;
    }
}

public class FooBar2 : FooBar1 { }

FooBar1 fb1 = new FooBar1();
FooBar2 fb2 = fb1.Foo<FooBar2>();

有什么方法可以做类似于C的事情吗?

更新1:

刚刚纠正了一些小的语法细节(我的意思是让Foo公开,然后返回T,而不是FooBar2).仍然得到编译器错误…当我删除模板行为时,错误消失了,到目前为止答案说我正在做的是有效的…但如果是,那么为什么我仍然得到错误?谢谢你的回答!

更新2:

Josh,这是实际的源代码(嗯,我认为是相关的,anwyay – 如果你认为我已经跳过了重要的一点,请告诉我).

// ImageMatrix.h
class ImageMatrix : public VImage
{
public:
    // ... varIoUs functions ...
    template<class T> T GetRotatedcopy(VDouble angle);
}

// ImageFilter.h
class ImageFilter : public ImageMatrix
{
    // ... varIoUs functions ...
}

// ImageMatrix.cpp
template<class T>
T ImageMatrix::GetRotatedcopy(VDouble angle)
{
    // ... create a new instance of ImageMatrix and return it.
}

// ImageProcessor.cpp
ImageFilter filter2 = filterPrototype.GetRotatedcopy<ImageFilter>(90);

这是实际的编译器错误:

/home/nick/Projects/ViMRID/vimrid/Debug/libvimrid.so: undefined reference to `vimrid::imaging::processing::ImageFilter vimrid::imaging::ImageMatrix::GetRotatedcopy(double)’

更新3:

顺便说一下,除了实现线之外的所有东西都位于一个库中;所以它是从一个单独的二进制文件调用的……这有关系吗?更正;它都在同一个图书馆里.但是所有块都是不同的文件.

更新4:

当我注释掉实现行(ImageFilter filter2 = filterPrototype …)时,它构建得很好,所以看起来就是这一行导致它……

更新5(已解决?):

还有问题……这可能是命名空间的问题吗?抓紧,好吧,我现在已经掌握了模板的概念! :)模板定义必须与声明一起在标题中(对吗?) – 所以现在我已将声明移到ImageMatrix.h中,所有内容都会编译.但是,我必须使用dynamic_cast来使其正常工作;这是正确的吗?如果我要离开,请纠正我!

// This is in the header file!
// Help!!! This looks really really smelly...
template<class T>
T ImageMatrix::GetRotatedcopy(VDouble angle)
{
    ImageMatrix image = _getRotatedcopy(angle);
    ImageMatrix *imagePtr = &image;
    return *dynamic_cast<T*>(imagePtr);
}

更新6:

参考更新5,当我不使用dynamic_cast时……

template<class T>
T ImageMatrix::GetRotatedcopy(VDouble angle)
{
    ImageMatrix image = _getRotatedcopy(angle);
    ImageMatrix *imagePtr = &image;
    //return *dynamic_cast<T*>(imagePtr);
    return *imagePtr;
}

……我收到这个错误……

../src/imaging/processing/../ImageMatrix.h: In member function ‘T vimrid::imaging::ImageMatrix::GetRotatedcopy(vimrid::VDouble) [with T = vimrid::imaging::processing::ImageFilter]’:
../src/imaging/processing/ImageProcessor.cpp:32:   instantiated from here
../src/imaging/processing/../ImageMatrix.h:45: error: conversion from ‘vimrid::imaging::ImageMatrix’ to non-scalar type ‘vimrid::imaging::processing::ImageFilter’ requested
make: *** [src/imaging/processing/ImageProcessor.o] Error 1

更新7:

另外,如果我在更新6中没有使用所有那些臭臭的代码……

class ImageMatrix : public VImage
{
public:
    template<class T> T GetRotatedcopy(VDouble angle);
private:
    ImageMatrix _getRotatedcopy(VDouble angle);
};

template<class T>
T ImageMatrix::GetRotatedcopy(VDouble angle)
{
    return _getRotatedcopy(angle);
}

…我得到了与更新6中相同的错误.

解决方法

是的,你非常接近,试试这个:
class FooBar1
{
public:
    template<class T> T Foo();
};

class FooBar2 : public FooBar1
{
};

template<class T>
T FooBar1::Foo()
{
    return T();
}

int main()
{
   FooBar1 fb1;
   FooBar2 fb2 = fb1.Foo<FooBar2>();
}

您遇到的问题是您将FooBar1 :: Foo()的返回类型指定为FooBar2,您应该只将其作为FooBar2.

如果你想为FooBar2做特定的事情,你可以专门研究FooBar2:

template<>
FooBar2 FooBar1::Foo<FooBar2>()
{
    return FooBar2();
}

编辑:
听起来你在编译器没有找到模板化GetRotatedcopy的定义时遇到问题. C中的模板相当挑剔,通常的做法是将整个模板实现放在头文件中.你可以试试这个:

class ImageMatrix : public VImage
{
public:
    // ... varIoUs functions ...
    template<class T> T GetRotatedcopy(VDouble angle)
    {
       // ... create a new instance of ImageMatrix and return it.
    }
};

编辑:
我找不到gcc文档,但这里有关于显式模板实例化和库的microsoft’s documentation,它给出了一些关于发生了什么的想法.您可能希望按照我之前的建议在头中包含实现,或者在库中调用GetRotatedcopy,或者在库中显式实例化它.有关语法,请参见下面的veefu’s answer.

与C#不同的原因是C语言中的模板实际上为每个不同的模板参数组合创建了一个全新的类/函数.例如矢量<诠释>是一个完全不同的类(使用不同的编译方法集)而不是vector< string>.有关更好的解释,请参阅Kevin’s answer.

至于当你不使用模板时错误消失,这实际上并没有告诉你多少,因为直到你实际实例化一个模板,它不会

RE更新5,6,7

您的dynamic_cast不起作用,只有当指针实际指向您要转换的类的实例时,才能使用它. (它的工作方式类似于C#中的as运算符).

我现在怀疑,你想要的是CRTP.你开始使用ImageFilter的一个实例,并希望在其上使用基类方法,并获得ImageFilter的新副本.尝试这些方面:

template <class T>
class ImageMatrix
{
public:
    T GetRotatedMatrix()
    {
        return T();
    }
};

class ImageFilter : public ImageMatrix<ImageFilter>
{
};

int main()
{
    ImageFilter filterPrototype;
    ImageFilter otherFilter = filterPrototype.GetRotatedMatrix();
}

否则,如果您真的想从ImageMatrix开始并将其转换为ImageFilter,则必须在ImageFilter上添加一个构造函数,该构造函数采用ImageMatrix.

c# – C是否支持单个泛型方法而不是泛型类?的更多相关文章

  1. xcode6.1 – Xcode 6.1中项目模板中缺少类前缀

    项目模板上曾经有一个类前缀字段,这有助于区分项目类和框架类.Xcode6.1项目模板中不再提供此功能.这背后的意图是什么?

  2. ios – 如何在Swift中使用没有类型参数的泛型类?

    解决方法Swift还不像Java那样支持wildcard-stylegenerics(即Animal

  3. ios – 如何在Swift中向下转换/转换结构的泛型类型

    我是否必须将这些存储为Any的数组,然后每次都将它们转换为或者我只是误解某些(或两者)?

  4. ios – 在XCTestCase子类中使用泛型有效吗?

    我有一个XCTestCase子类,看起来像这样.为了简洁起见,我已经删除了setup()和tearDown方法:它的子类看起来像这样:在理论上,这应该按预期工作–编译器不会抱怨任何事情.但是只是当我运行测试用例时,setup()方法甚至没有被调用.但是,它表明当testName()方法应该失败时,测试已经过去了.使用泛型是一个问题吗?我可以很容易地想到很多非通用的方法,但是我很想写这样的测试用例.这是XCTest在Objective-C和Swift之间的互操作性?Ergo您的通用XCTestCase子类不

  5. 泛型 – Xcode构建错误时,我添加枚举到泛型类?

    为什么在将泛型类添加到枚举时会收到错误:错误:但是当我这样做时,我没有收到错误:或这个:解决方法您不能将任何类型嵌套在通用的类型中,反之亦然.换句话说,你不能像类,结构和枚举这样做的事情:和乃至苹果人explained的限制原因:It’sanimplementationlimitation.We’llremovetherestrictiononceourcompilerandruntimearea

  6. ios – 如何通过Swift中的泛型类型构造一个属性?

    我在swift中创建了一个泛型类,我想使用“AdaptorType”类型初始化一个适配器,但是我收到一个编译错误我也尝试在init()中初始化它,但是同样的问题在于使用通用类型AdaptorType初始化适配器属性的正确方法是什么?

  7. ios – Equatable实现似乎不适用于泛型

    我仍然在与Swift仿制药作斗争.今天我发现我的Equatable协议实现不起作用,如果它是从泛型类调用的.我的模特课:类,使用泛型类型:它的子类:当我调用TrackingCache实例的removeEntities方法时,我总是在输出中得到相等的:false,即使id是相同的.但是,如果我直接将方法移动到TrackingCache类,它似乎工作正常!

  8. 泛型 – MonoTouch和支持变体通用接口

    如果是这样,MonoTouch中针对这种情况的推荐解决方法是什么?解决方法这实际上取决于编译器而不是Mono版本.IOW有些东西可能适用于Mono2.10而不适用于MonoTouch6.x.当前版本的MonoTouch附带了smcs编译器和基于2.1的配置文件.较新的功能,如协方差,需要一个完整的4.0编译器和运行时.未来版本的MonoTouch将提供4.0/4.5运行时和编译器.

  9. 寒城攻略:Listo 教你 25 天学会 Swift 语言 - 24 Generics

    它可以避免重复的代码,用一种清晰和抽象的方式来表达代码的意图//泛型是Swift强大特征中的一个,许多Swift标准库都是通过泛型代码构建出来的。{forinenumerate{//遍历索引固定字符串的下标ifvalue==valuetoFind{returnindex}}returnnil}letstrings=["cat","dog","llama","parakeet"]ifletfoundindex=findStringIndex{p

  10. Swift语法基础:7 - Swift的Generics

    在前面,我们知道了Swift中的Protocol和Extensions,现在我们来看看另一个东西:Generics(泛型)1.泛型的声明以及简单使用PS:所谓的泛型其实就是一个比较特殊的数组,它可以存储不同类型的数据,这样子我们在写方法的时候,就不需要再写多一个相同功能而类型不同的方法了.2.枚举类型中的泛型3.特定需求的泛型PS:如果你需要某个指定样式的泛型,那么就必须得在泛型里加上where这

随机推荐

  1. c# – (wpf)Application.Current.Resources vs FindResource

    所以,我正在使用C#中的WPF创建一个GUI.它看起来像这样:它现在还没有完成.这两行是我尝试制作一种数据表,它们在XAML中是硬编码的.现在,我正在C#中实现添加新的水果按钮功能.我在XAML中有以下样式来控制行的背景图像应该是什么样子:因此,在代码中,我为每列col0,col1和col2创建一个图像,如果我使用以下代码,它添加了一个如下所示的新行:如你所见,它不太正确……为什么一个似乎忽略了一些属性而另一个没有?

  2. c# – 绑定DataGridTemplateColumn

    似乎我已经打了个墙,试图在DataGrid上使用DataTemplates.我想要做的是使用一个模板来显示每个单元格的两行文本.但是似乎无法以任何方式绑定列.以下代码希望显示我想做的事情.注意每个列的绑定:模板列没有这样的东西,因此,这个xaml不可能工作.我注定要将整个DataTemplate复制到每个列,只是对每个副本都有不同的约束?解决方法我不完全确定你想要做什么,但如果您需要获取整行的DataContext,可以使用RelativeSource绑定来移动视觉树.像这样:

  3. c# – 学习设计模式的资源

    最近我来到了这个设计模式的概念,并对此感到非常热情.你能建议一些帮助我深入设计模式的资源吗?

  4. c# – 是否有支持嵌入HTML页面的跨操作系统GUI框架?

    我想开发一个桌面应用程序来使用跨系统,是否有一个GUI框架,允许我为所有3个平台编写一次代码,并具有完全可脚本化的嵌入式Web组件?我需要它有一个API来在应用程序和网页之间进行交流.我知道C#,JavaScript和一些python.解决方法Qt有这样的事情QWebView.

  5. c# – 通过字符串在对象图中查找属性

    我试图使用任意字符串访问嵌套类结构的各个部分.给出以下(设计的)类:我想要从Person对象的一个实例的“PersonsAddress.HousePhone.Number”获取对象.目前我正在使用反思来做一些简单的递归查找,但是我希望有一些忍者有更好的想法.作为参考,这里是我开发的(crappy)方法:解决方法您可以简单地使用标准的.NETDataBinder.EvalMethod,像这样:

  6. c# – 文件下载后更新页面

    FamilyID=0a391abd-25c1-4fc0-919f-b21f31ab88b7&displaylang=en&pf=true它呈现该页面,然后使用以下元刷新标签来实际向用户提供要下载的文件:你可能需要在你的应用程序中做类似的事情.但是,如果您真的有兴趣在文件完全下载后执行某些操作,那么您的运气不佳,因为没有任何事件可以与浏览器进行通信.执行此操作的唯一方法是上传附件时使用的AJAXupload.

  7. c# – 如何在每个机器应用程序中实现单个实例?

    我必须限制我的.net4WPF应用程序,以便每台机器只能运行一次.请注意,我说每个机器,而不是每个会话.我使用一个简单的互斥体实现单实例应用程序,直到现在,但不幸的是,这样一个互斥是每个会话.有没有办法创建机器互连,还是有其他解决方案来实现每个机器应用程序的单个实例?

  8. c# – WCF和多个主机头

    我的雇主网站有多个主机名,都是同一个服务器,我们只是显示不同的皮肤来进行品牌宣传.不幸的是,在这种情况下,WCF似乎不能很好地工作.我试过overridingthedefaulthostwithacustomhostfactory.这不是一个可以接受的解决方案,因为它需要从所有主机工作,而不仅仅是1.我也看过thisblogpost,但是我无法让它工作,或者不是为了解决我的问题.我得到的错误是“这

  9. c# – ASP.NET MVC模型绑定与表单元素名称中的虚线

    我一直在搜索互联网,试图找到一种方式来容纳我的表单元素的破折号到ASP.NET的控制器在MVC2,3或甚至4中的默认模型绑定行为.作为一名前端开发人员,我更喜欢在我的CSS中使用camelCase或下划线进行破折号.在我的标记中,我想要做的是这样的:在控制器中,我会传入一个C#对象,看起来像这样:有没有办法通过一些正则表达式或其他行为来扩展Controller类来适应这种情况?我讨厌这样的事实,我必须这样做:甚至这个:思考?

  10. c# – 用户界面设计工具

    我正在寻找一个用户界面设计工具来显示文档中可能的GUI.我不能生成代码.我知道MicrosoftVisio提供了一个功能.但有什么办法吗?您使用哪种软件可视化GUI?

返回
顶部