Java通用问题(Java Generic Question)

下面的代码编译,但如果我取消注释注释行,它不会,我很困惑为什么。 HashMap确实扩展了AbstractMap,并且声明map的第一行编译正常。

import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;

public class Test {

    public static void main(String args[]) {
        Map<String, ? extends AbstractMap<String, String>> map = new HashMap<String, HashMap<String, String>>();
        //map.put("one", new HashMap<String, String>());
    }
}

而且,我知道“正确的方式”是这样的:

import java.util.HashMap;
import java.util.Map;

public class Test {

    public static void main(String args[]) {
        Map<String, Map<String, String>> map = new HashMap<String, Map<String, String>>();
        map.put("one", new HashMap<String, String>());
    }
}

The following code compiles but if I uncomment the commented line, it does not and I am confused why. HashMap does extend AbstractMap and the first line where map is declared compiles fine.

import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;

public class Test {

    public static void main(String args[]) {
        Map<String, ? extends AbstractMap<String, String>> map = new HashMap<String, HashMap<String, String>>();
        //map.put("one", new HashMap<String, String>());
    }
}

And, I know the "right way" is this:

import java.util.HashMap;
import java.util.Map;

public class Test {

    public static void main(String args[]) {
        Map<String, Map<String, String>> map = new HashMap<String, Map<String, String>>();
        map.put("one", new HashMap<String, String>());
    }
}

原文:https://stackoverflow.com/questions/5974065
2023-04-30 11:04

满意答案

你是对的。 检测无限递归而不限制模板元编程上的递归堆栈帧意味着找到停止问题的替代解决方案。

理论上有几种特殊情况是可检测的。 例如,如果您可以确保递归的引用透明性,并且最后一个函数调用接收到与实际调用相同的参数,那么您将进行无限递归调用。 C ++不提供模板元编程的参考透明度保证。


Your are correct. Detecting an infinite recursion without limiting the recursion stack frames on template meta programming would mean finding an alternative solution to the halting problem.

There are a few special cases which are, in theory, detectable. For example, if you can ensure referential transparency on the recursion and if the last function call receives the same parameters as the actual one, you are on an infinite recursive call. C++ offers no referential transparency warranty on template meta programming.

相关问答

更多

模板(元)编程总是只有一种实现方式吗?(Does template (meta)programming has always only one way of implementation?)

一般来说,缺乏TMP中可用的功能以及功能的相对简单性 - 如果不是必须表达的方式 - 意味着很少有多个实现显着不同。 Generally speaking, the lack of features available in TMP and the relative simplicity of the functionality- if not the way it has to be expressed- means that there's very rarely more than one ...

什么样的C ++模板编程可以称为“元编程”?(What kind of C++ template programming can be called “meta programming”? [closed])

“元编程”在非正式演讲中用于指代各种编程技术: 有关类型的信息,即“类型特征”。 这是最直接的meta类型,因为“meta”在这里意味着“关于某事” (Ab)使用C预处理器或模板。 你不是真的在“C ++”编程,而是一个子语言。 IOCCC有很多人使用C预处理器来完成各种完整的程序,比如河内塔和计算素数。 模板元程序的“经典”示例是计算斐波纳契。 换句话说,你正在“正常”C ++的正常范围之外创建程序,这使得这种用法类似于元游戏 Quines,创建程序,使程序,程序,自托管编译器等。这里“元”意味...

C ++模板元编程:重载运算符(C++ template meta programming: overloading operators)

我找到了解决方案。 我在基类中创建了一个typedef: template<typename Input> class Base { public: virtual ~Base() = default; virtual bool operator()(const Input& input) const = 0; typedef Input inputType; }; 我把运算符重载到了课外: template <typename Lhs, typename Rh...

编译器如何理解递归?(How do compilers understand recursion?)

但编译器如何实际解释递归函数? 它如何在自己的定义中使用函数? 要理解这一点,你只需要站在如何编译器解释一个函数。 对于C来说,函数只是一个符号,或者指向内存中入口地址的指针。 直观但不是严格的,函数调用会被编译为这样的汇编指令: CALL address_of_function 看到? 编译器不需要知道函数是否递归。 它只是让CPU跳转到函数输入的地址并继续执行指令。 这就是为什么我们可以使用该功能,即使它的定义没有完成。 编译器只需要知道一个起始地址或一个符号,然后它就会知道跳到哪里。 函数...

使用成员函数指针进行模板元编程?(Template meta-programming with member function pointers?)

查看有关指向非静态成员主题的讨论作为模板参数。 看起来VC ++实现存在问题。 Check out this discussion on the subject of pointers-to-nonstatic-members as template parameters. It looks like there are issues with the VC++ implementation.

C ++模板元编程:从模板模板参数继承(C++ Template Meta Programming: Inheritance from template template parameter)

由于T1仅用于模板特化选择,因此您不必使用Buffer本身。 您可以改用标签类型。 在命名空间中将其删除也可以避免使用标记污染封闭命名空间的其余部分。 #include <type_traits> template <typename T1, typename T2, typename is_allocated> struct mutable_storage {}; namespace storage_tags { struct Buffer_T {}; } template < ...

如何在c ++中编写元编程模板的最后一个递归(How to write last recursion for meta-programming template in c++)

使P成为模板和专业化的一部分。 首先,递归调用是: return (P + N + r) * cutom_imagined<N - 1, P>::function(r); 其次,专门化现在是部分的: template <unsigned int P> struct cutom_imagined<0, P> { static unsigned int function(unsigned int) { return 1; } }; Make P part of the template a...

模板元编程,使用可变模板:编译器错误(Template Meta-programming, with Variadic Templates: compiler error)

直接的问题是你正在定义一个没有通用模板的type_holder的专业化。 另外,还有一个简单的错字( typeholder而不是type_holder )。 解决这两个问题使得它可以与其他编译器一起编译: template <int, typename T> struct type_holder; template <int k, typename T, typename ...M> struct type_holder<k, ItemSet<T, M...>> { typedef ty...

编译器是否可以在模板元编程中识别递归问题?(Can compilers identify recursion issues in Template Meta programming?)

你是对的。 检测无限递归而不限制模板元编程上的递归堆栈帧意味着找到停止问题的替代解决方案。 理论上有几种特殊情况是可检测的。 例如,如果您可以确保递归的引用透明性,并且最后一个函数调用接收到与实际调用相同的参数,那么您将进行无限递归调用。 C ++不提供模板元编程的参考透明度保证。 Your are correct. Detecting an infinite recursion without limiting the recursion stack frames on template met...

编译器是否保证优化模板生成的递归代码?(Are compilers guaranteed to optimize recursive code generated by templates?)

Bjarne关于编译时递归的评论指的是评估模板的方式,而不是生成的代码的工作方式。 例如,考虑以下模板: template <typename... Args> struct Length; template <> struct Length<> { static const size_t value = 0; }; template <typename First, typename... Rest> struct Length { static const size_t val...

相关文章

更多

Solr Cache使用介绍及分析,包括LRUCache、filterCache、queryResultCache、documentCache、Generic Caches

本文将介绍Solr查询中涉及到的Cache使用及相关的实现。Solr查询的核心类就是SolrIndex ...

java通用返回对象

java通用返回对象返回对象通常包括是否成功、响应码、接口响应描述、响应实体几个属性

《JAVA代码规范》(四)通用代码格式 - 注释(2.7)

Java程序有两类注释:实现注释(implementation comments)和文档注释(docu ...

《JAVA代码规范》(二)通用代码格式 - 文件组织(2.1)

2 通用代码格式 2.1 文件组织 一个文件由被空行分割而成的段落以及标识每个段落的可选注释共同组成。 ...

《JAVA代码规范》(五)通用代码格式 - 声明(2.8)

2.8 声明 2.8.1 每行声明变量的数量 推荐一行一个声明,因为这样以利于写注释。亦即, int ...

java该词,国内程序员和国外程序员念法一样吗,通用念法是什么?

java,国内程序员和国外程序员念法一样吗,通用念法是什么? 见个博士念作扎我,感觉他好像没接触过j ...

《JAVA代码规范》(三)通用代码格式 - 缩进、行长度、换行、空行、空格(2.2-2.6)

4个空格常被作为缩进排版的一个单位,以表示缩进,显示程序的层次级别,增加程序的可读性。不要在源代码中保 ...

《JAVA代码规范》(六)通用代码格式 - 语句、SQL(2.9-2.10)

简单语句:每行至多包含一条语句;复合语句:复合语句是包含在大括号中的语句序列,形如"{ 语句 }";返 ...

Hadoop Java程序-files功能测试

之前一直用Hadoop streaming方式,-file功能非常实用,可以动态上传文件,例如一些配置 ...

最新问答

更多

获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)

我用Google搜索了一个解决方案。 “EnumDisplayModeProvider”是我自己设置网站的各种模式的枚举。 public EnumDisplayModeProvider GetDisplayModeId() { foreach (var mode in DisplayModeProvider.Instance.Modes) if (mode.CanHandleContext(HttpContext)) {

如何通过引用返回对象?(How is returning an object by reference possible?)

这相对简单:在类的构造函数中,您可以分配内存,例如使用new 。 如果你制作一个对象的副本,你不是每次都分配新的内存,而是只复制指向原始内存块的指针,同时递增一个也存储在内存中的引用计数器,使得每个副本都是对象可以访问它。 如果引用计数降至零,则销毁对象将减少引用计数并仅释放分配的内存。 您只需要一个自定义复制构造函数和赋值运算符。 这基本上是共享指针的工作方式。 This is relatively easy: In the class' constructor, you allocate m

矩阵如何存储在内存中?(How are matrices stored in memory?)

正如它在“熵编码”中所说的那样,使用Z字形图案,与RLE一起使用,在许多情况下,RLE已经减小了尺寸。 但是,据我所知,DCT本身并没有给出稀疏矩阵。 但它通常会增强矩阵的熵。 这是compressen变得有损的点:输入矩阵用DCT传输,然后量化量化然后使用霍夫曼编码。 As it says in "Entropy coding" a zig-zag pattern is used, together with RLE which will already reduce size for man

每个请求的Java新会话?(Java New Session For Each Request?)

你是如何进行重定向的? 您是否事先调用了HttpServletResponse.encodeRedirectURL()? 在这里阅读javadoc 您可以使用它像response.sendRedirect(response.encodeRedirectURL(path)); The issue was with the path in the JSESSIONID cookie. I still can't figure out why it was being set to the tomca

css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)

我认为word-break ,如果你想在一个单词中打破行,你可以指定它,这样做可以解决问题: .column { word-break:break-all; } jsFiddle演示。 您可以在此处阅读有关word-break属性的更多信息。 I think word-break, with which you can specify if you want to break line within a word, will do the trick: .column { word-break

无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)

我认为您忘记在分类时间内缩放输入图像,如train_test.prototxt文件的第11行所示。 您可能应该在C ++代码中的某个位置乘以该因子,或者使用Caffe图层来缩放输入(请查看ELTWISE或POWER图层)。 编辑: 在评论中进行了一次对话之后,结果发现在classification.cpp文件中错误地删除了图像均值,而在原始训练/测试管道中没有减去图像均值。 I think you have forgotten to scale the input image during cl

xcode语法颜色编码解释?(xcode syntax color coding explained?)

转到: Xcode => Preferences => Fonts & Colors 您将看到每个语法高亮颜色旁边都有一个简短的解释。 Go to: Xcode => Preferences => Fonts & Colors You'll see that each syntax highlighting colour has a brief explanation next to it.

在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)

你考虑过第三方拼写检查吗? 您可以将在C#中开发的自定义WinForms控件插入访问数据库吗? VB6控件怎么样? 如果你能找到一个使用第三方库进行拼写检查的控件,那可能会有效。 Have you considered a third party spell checker? Can you insert a custom WinForms controls developed in C# into an access database? What about a VB6 control? If

从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)

我有同样的问题,因为我在远程服务器上有两个图像,我需要在每天的预定义时间复制到我的本地服务器,这是我能够提出的代码... try { if(@copy('url/to/source/image.ext', 'local/absolute/path/on/server/' . date("d-m-Y") . ".gif")) { } else { $errors = error_get_last(); throw new Exception($err

从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))

我不确定我完全明白你在说什么。 你能编辑你的帖子并包含你正在做的Subversion命令/操作的特定顺序吗? 最好使用命令行svn客户端,以便容易为其他人重现问题。 如果您只是想获取文件的旧副本(即使该文件不再存在),您可以使用如下命令: svn copy ${repo}/trunk/moduleA/file1@${rev} ${repo}/trunk/moduleB/file1 其中${repo}是您的存储库的URL, ${rev}是您想要的文件的版本。 这将恢复该文件的旧版本,包括最高版本