我正在尝试理解 P0091r3 (已被纳入当前 C++ 标准草案 N4606 的“类模板的模板参数推导”论文)。
我相信我理解它在最简单的可能情况下是如何工作的,其中 template-name 标识单个模板:
template<class T>
struct S {
S(T);
S(const std::vector<T>&);
};
int main()
{
std::vector<int> v;
auto s = S(v);
}
S标识主模板,因此我们创建一个虚构的重载集,其中包含
template<class T> void Sctor(T);
template<class T> void Sctor(const std::vector<T>&);
并对虚构调用执行重载决议
Sctor(v)
确定在这种情况下我们要调用虚构的 Sctor(const std::vector<T>&) [with T=int] .这意味着我们最终调用了 S<int>::S(const std::vector<int>&)一切都很好。
我不明白的是,在存在部分特化的情况下这应该如何工作。
template<class T>
struct S {
S(T);
};
template<class T>
struct S<std::list<T>> {
S(const std::vector<T>&);
};
int main()
{
std::vector<int> v;
auto s = S(v);
}
我们凭直觉想要在这里调用S<std::list<int>>::S(const std::vector<int>&) .那是我们实际得到的吗?这是在哪里指定的?
基本上我不直观地理解 P0091r3 的“由 template-name 指定的类模板”是什么意思:这是否意味着主模板,或者它是否包括所有部分特化和显式完整还有特化?
(我也不明白 P0091r3 对 §7.1.6.2p2 的更改如何不破坏使用注入(inject)类名的代码,例如
template<class T>
struct iterator {
iterator& operator++(int) {
iterator result = *this; // injected-class-name or placeholder?
//...
}
};
但这完全是另一个问题。)
类模板推导和显式推导指南是否在任何现有版本的 Clang 或 GCC 中受支持(可能在 -f 标志下,如 -fconcepts 是)?如果是这样,我可以在现实生活中尝试其中的一些示例,并且可能会消除一半的困惑。
最佳答案
提案略过了这一点,但我认为其意图是仅考虑主类模板的构造函数。证据是新的 [class.template.deduction] 有:
- For each constructor of the class template designated by the template-name, a function template with the following properties is a candidate: [...]
如果我们谈论的是“the”类模板,那么这是主要的类模板,特别是因为类模板部分特化无法通过名称查找找到 ([temp.class.spec]/6)。这也是原型(prototype)实现(见下文)的行为方式。
在本文中,类模板部分特化在“隐式推导指南的优缺点”一节中进行了考虑,而是担心主类模板中的构造函数可能会触发硬(非 SFINAE)错误:
template<class T> struct X {
using ty = T::type;
static auto foo() { return typename T::type{} };
X(ty); #1
X(decltype(foo())); #2
X(T);
};
template<class T>
struct X<T*> {
X(...);
};
X x{(int *)0};
您请求考虑类模板偏特化构造函数的请求从表面上看是合理的,但请注意,这可能会导致歧义:
template<class T> struct Y { Y(T*); };
template<class T> struct Y<T*> { Y(T*); };
Y y{(int*) 0};
隐式生成的演绎指南可能需要通过类模板的特化来排序(作为决胜局)。
如果您想尝试原型(prototype)实现,作者已在 github 上发布了他们的 clang 分支:https://github.com/faisalv/clang/tree/clang-ctor-deduction .
论文中的讨论(“A note on injected class names”)表明注入(inject)类名优先于模板名;添加措辞以确保这一点:
The template-name shall name a class template that is not an injected-class-name.
关于c++ - 关于C++17中类模板参数推导的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39363961/
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
由于fast-stemmer的问题,我很难安装我想要的任何rubygem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=