我有一个模板类 C,它有一个非类型但引用类型 P 的模板参数:
class P {
public:
int x;
int y;
};
template <const P &x>
class C {
public:
const int &f() { return x.x; }
};
我声明了一个 P 类型的全局变量:
P p = {33,44};
我还声明了一个返回对 p 的引用的函数:
constexpr const P &h() { return p; }
然后尝试在下面使用这些:
C<p> o; // line 1
C<h()> oo; // line 2
当然,我对第一个实例化没有问题,但第二个实例化。我的编译器提示:
error: non-type template argument does not refer to any declaration
为什么会这样?我无法在规范中找到反对它的论据。我不确定这与 Calling constexpr in default template argument 中的问题完全相同。 ,其中讨论的是关于嵌套实例化的实例化点。这更像是一个类型问题,但是哪一个呢?我的函数 h() 返回对明确定义类型的明确定义变量 (const P &) 的引用。我预计会发生一些内联以给出正确的结果,但事实并非如此。你能告诉我为什么吗?
将函数声明为内联不会改变任何问题。
使用 Apple LLVM 版本 6.0 (clang-600.0.56)(基于 LLVM 3.5svn 进行实验。我还尝试使用 g++-mp-4.8 (MacPorts gcc48 4.8.3_2 ) 4.8.3 报错为:
'h()' is not a valid template argument for type 'const P&' because it is not an object with external linkage
看起来我对 h() 的调用(这是一个 constexpr 所以编译时可计算)不被视为这样......
我忘了说如果我们尝试像这样的另一个引用,问题是一样的:
const P &pp = p;
然后
C<pp> oo;
这次第一个编译器说:
non-type template argument of reference type 'const P &' is not an object
第二个:
error: could not convert template argument 'pp' to 'const P &'
pp 不是对象? pp 不是 const P& 类型?好吧,我可以按原样使用它...我知道它是一个引用,但与 native 引用没有区别,或者?
最佳答案
此限制似乎受以下提议 Allow constant evaluation for all non-type template arguments 的约束,仍在尝试确定此提案的状态。它说:
The syntactic restrictions for pointers, references, and pointers to members are awkward and prevent reasonable refactorings. For instance:
template<int *p> struct A {}; int n; A<&n> a; // ok constexpr int *p() { return &n; } A<p()> b; // error
并进一步说:
The historical reason for the restriction was most likely that C++ previously did not have a sufficiently strong specification for constant expressions of pointer, reference, or pointer-to-member type. However, that is no longer the case. The status quo is that an implementation is required to evaluate such a template argument, but must then discard the result if it turns out to not be null.
In addition to the above, the restriction to entities with linkage is an artifact of exported templates, and could have been removed when the linkage restrictions on template type parameters were removed.
它会删除带有此限制的注释的这一部分:
unnamed lvalues, and named lvalues with no linkage
整条注释如下:
Temporaries, unnamed lvalues, and named lvalues with no linkage are not acceptable template-arguments when the corresponding template-parameter has reference type.
更新
本提案的修订版N4268是 adopted into the working draft at Urbana我们可以看到最新工作草案中的变化N4296 .新说明如下:
A temporary object is not an acceptable template-argument when the corresponding template-parameter has reference type
规范部分是 14.3.2 (temp.arg.nontype) 段落 1 在这个提案中会说:
For a non-type template-parameter of reference or pointer type, the value of the constant expression shall not refer to (or for a pointer type, shall not be the address of):
- a subobject (1.8),
- a temporary object (12.2),
- a string literal (2.14.5),
- the result of a typeid expression (5.2.8), or
- a predefined func variable (8.4.1).
我们可以在最新的标准草案 N4296 中找到这个新措辞.
看起来这项更改实际上已在 clang HEAD 中实现,请查看您的代码是否正常运行 live ,使用 -std=c++1z 标志。这意味着更改应该是 C++17 的一部分,假设后续更改不会逆转或改变它。
关于c++ - 带有 constexpr 函数失败的模板实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27410465/
我的瘦服务器配置了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_”……这
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案
我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_