- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
#include <type_traits>
template <typename T>
struct C;
template<typename T1, typename T2>
using first = T1;
template <typename T>
struct C<first<T, std::enable_if_t<std::is_same<T, int>::value>>>
{
};
int main ()
{
}
不同编译器的编译结果:
MSVC:
error C2753: 'C': partial specialization cannot match argument list for primary template
gcc-4.9:
error: partial specialization 'C' does not specialize any template arguments
clang 所有版本:
error: class template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list
gcc-5+:编译成功
另外,我想指出一些琐碎的特化,例如:
template<typename T>
struct C<T>
{
};
gcc 编译成功失败。因此,似乎发现我最初的示例中的特化并非易事。所以我的问题是 - C++ 标准是否明确禁止这样的模式?
最佳答案
关键段落是[temp.class.spec]/(8.2) ,这要求部分特化比主模板更特化。 Clang 实际上提示的是参数列表与主模板的相同:这已从 [temp.class.spec]/(8.3) 中删除。由 issue 2033 (声明该要求是多余的)最近,所以还没有在 Clang 中实现。但是,鉴于它接受您的代码段,它显然已在 GCC 中实现;它甚至compiles the following ,也许出于同样的原因,它会编译您的代码(它也只能从版本 5 开始工作):
template <typename T>
void f( C<T> ) {}
template <typename T>
void f( C<first<T, std::enable_if_t<std::is_same<T, int>::value>>> ) {}
即它承认声明是不同的,因此必须执行一些问题的解决方案1980 .它没有发现第二个重载更专业(参见 Wandbox 链接),但是,这是不一致的,因为它应该根据 (8.2) 中的上述约束来诊断您的代码。
可以说,当前的措辞使您的示例的部分排序按预期工作†:[temp.deduct.type]/1提到从类型推导中,
Template arguments can be deduced in several different contexts, but in each case a type that is specified in terms of template parameters (call it
P
) is compared with an actual type (call itA
), and an attempt is made to find template argument values […] that will makeP
, after substitution of the deduced values (call it the deducedA
), compatible withA
.
现在通过 [temp.alias]/3 ,这意味着在部分特化的函数模板是参数模板的部分排序步骤中,替换为 is_same
会产生错误(因为公共(public)库实现只使用必须失败的部分特化), enable_if
失败。‡ 但是这种语义在一般情况下并不令人满意,因为我们可以构造一个通常成功的条件,因此唯一的合成类型满足它,并且推导双向成功。
大概,最简单和最强大的解决方案是在部分排序期间忽略丢弃的参数(使您的示例格式错误)。在这种情况下,人们也可以将自己定位于实现的行为(类似于问题 1157 ):
template <typename...> struct C {};
template <typename T>
void f( C<T, int> ) = delete;
template <typename T>
void f( C<T, std::enable_if_t<sizeof(T) == sizeof(int), int>> ) {}
int main() {f<int>({});}
两者Clang和 GCC将此诊断为调用已删除的函数,即同意第一个重载比另一个重载更专业。 #2 的关键属性似乎是第二个模板参数是依赖的,但 T
仅出现在非推导上下文中(如果我们将 int
更改为 T
在 #1 中,没有任何变化)。所以我们可以使用丢弃的(和依赖的?)模板参数的存在作为决胜局:这样我们就不必推理合成值的性质,这是现状,并且在你的情况下也得到合理的行为,这将是格式良好的。
† @T.C.提到通过 [temp.class.order] 生成的模板目前将被解释为一个多重声明的实体——再次,请参阅问题 1980。 .在这种情况下,这与标准语言没有直接关系,因为措辞从来没有提到这些函数模板是被声明的,更不用说在同一个程序中了;它只是指定它们,然后回退到函数模板的过程。
‡ 执行此分析所需的深度实现并不完全清楚。问题 1157演示“正确”确定模板的域是否是其他域的适当子集所需的详细程度。将部分排序实现得如此复杂既不实际也不合理。但是,脚注部分只是表明该主题不一定未指定,而是有缺陷。
关于c++ - 下面的代码是否应该按照 C++ 标准编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41143524/
我正在尝试在Elasticsearch中返回的值中考虑地理位置的接近性。我希望近距离比某些字段(例如legal_name)重要,但比其他字段重要。 从文档看来,当前的方法是使用distance_fea
我是Elasticsearch的初学者,今天在进行“多与或”查询时遇到问题。 我有一个SQL查询,需要在Elastic中进行转换: WHERE host_id = 999 AND psh_pid =
智能指针应该/可以在函数中通过引用传递吗? 即: void foo(const std::weak_ptr& x) 最佳答案 当然你可以通过const&传递一个智能指针。 这样做也是有原因的: 如果接
我想执行与以下MYSQL查询等效的查询 SELECT http_user, http_req_method, dst dst_port count(*) as total FROM my_table
我用这两个查询进行测试 用must查询 { "size": 200, "from": 0, "query": { "bool": { "must": [ { "mat
我仍在研究 Pro Android 2 的简短服务示例(第 304 页)同样,服务示例由两个类组成:如下所示的 BackgroundService.java 和如下所示的 MainActivity.j
给定标记 like this : header really_wide_table..........................................
根据 shouldJS 上的文档网站我应该能够做到这一点: ''.should.be.empty(); ChaiJS网站没有使用 should 语法的示例,但它列出了 expect 并且上面的示例似乎
我在 Stack Overflow 上读到一些 C 函数是“过时的”或“应该避免”。你能给我一些这种功能的例子以及原因吗? 这些功能有哪些替代方案? 我们可以安全地使用它们 - 有什么好的做法吗? 最
在 C++11 中,可变参数模板允许使用任意数量的参数和省略号运算符 ... 调用函数。允许该可变参数函数对每个参数做一些事情,即使每个参数的事情不是一样的: template void dummy(
我在我从事的项目之一上将Shoulda与Test::Unit结合使用。我遇到的问题是我最近更改了此设置: class MyModel :update end 以前,我的(通过)测试看起来像这样: c
我该如何做 or使用 chai.should 进行测试? 例如就像是 total.should.equal(4).or.equal(5) 或者 total.should.equal.any(4,5)
如果您要将存储库 B 中的更改 merge 到存储库 A 中,是否应该 merge .hgtags 中的更改? 存储库 B 可能具有 A 中没有的标签 1.01、1.02、1.03。为什么要将这些 m
我正在尝试执行X AND(y OR z)的查询 我需要获得该代理为上市代理或卖方的所有已售属性(property)。 我只用 bool(boolean) 值就可以得到9324个结果。当我添加 bool
我要离开 this教程,尝试使用 Mocha、Supertest 和 Should.js 进行测试。 我有以下基本测试来通过 PUT 创建用户接受 header 中数据的端点。 describe('U
我正在尝试为 Web 应用程序编写一些 UI 测试,但有一些复杂的问题希望您能帮助我解决。 首先,该应用程序有两种模式。其中一种模式是“训练”,另一种是“现场”。在实时模式下,数据直接从我们的数据库中
我有一个规范: require 'spec_helper' # hmm... I need to include it here because if I include it inside desc
我正在尝试用这个测试我在 Rails 中的更新操作: context "on PUT to :update" do setup do @countdown = Factory(:count
我还没有找到合适的答案: onclick="..." 中是否应该转义 &(& 符号)? (或者就此而言,在每个 HTML 属性中?) 我已经尝试在 jsFiddle 和 W3C 的验证器上运行转义和非
import java.applet.*; import java.awt.*; import java.awt.event.*; public class Main extends Applet i
我是一名优秀的程序员,十分优秀!