考虑以下代码:
#include <iostream>
template<class T>
struct foo {};
template<>
struct foo<int> {
static constexpr char value[] = "abcde";
};
template<class T>
struct bar {
static constexpr char value[] = "abcde";
};
template<class T>
struct baz {
static constexpr int value = 12345;
};
int main() {
char c = foo<int>::value[2];
char d = bar<int>::value[2];
int e = baz<int>::value;
std::cout << c << d << e << "\n";
}
编译时:clang++ -std=c++14 ./test_foo.cc ,我收到 undefined symbol 的链接器错误:bar<int>::value和 foo<int>::value .当我更改为 clang++ -std=c++17 ,那么只有一个 undefined symbol :foo<int>::value .我的 clang++ 版本是 5.0。
然而,当我尝试 g++ -std=c++14 ./test_foo.cc ,编译成功。我的 g++ 版本是 5.4.0。
我有两件事要问。
1) 从 C++ 标准的角度来看,哪个编译器的行为正确?
我用谷歌搜索并阅读了许多 cppreference 页面,但没有发现任何与这种现象真正相关的内容。特别是对于带有 -std=c++17 的 clang++ ,行为真的很奇怪,因为bar<int>通过了但是foo<int>失败,唯一的区别是 foo<int>是一个专业。我从http://en.cppreference.com/w/cpp/language/constexpr读到那个
A constexpr specifier used in a function or static member variable (since C++17) declaration implies inline.
因此似乎没有理由进行模板特化foo<int>失败。此外,我在链接之前查看了生成的目标文件,访问 foo<int>::value[2]; 没有像人们期望的那样在编译时完成。我高度怀疑 clang++ 编译器有问题。
2) 如何处理这个 clang++ 链接错误?
我试过类似 Undefined reference to static constexpr char[] 的东西, 但最后我找不到任何方法来克服这个链接错误。所以我只是想知道是否有办法让这个链接成功。
最佳答案
直到 C++17,原因与 the question you found 中所述完全相同(我认为 Shafik Yaghmour 发布的答案更准确地解释了这个问题)。简而言之,定义一个constexpr如果成员是 odr-used,静态数据成员仍然是必需的.
您可以 resolve the problem通过提供这些变量的定义直到 C++17(即使用 -std=c++14)。
自 C++17 起,当前标准在 [dcl.constexpr] paragraph 1 中说
... A function or static data member declared with the
constexprspecifier is implicitly an inline function or variable ([dcl.inline]).
A declaration is a definition unless
...
it declares a non-inline static data member in a class definition ([class.mem], [class.static]),
...
因此不需要命名空间范围内的此类定义。
此外,现行标准在[depr.static_constexpr] paragraph 1说
For compatibility with prior C++ International Standards, a constexpr static data member may be redundantly redeclared outside the class with no initializer. This usage is deprecated. [ Example:
struct A { static constexpr int n = 5; // definition (declaration in C++ 2014) }; constexpr int A::n; // redundant declaration (definition in C++ 2014)— end example ]
所以你最好从 C++17 开始避免这样的定义。
When I change to
clang++ -std=c++17, then only one undefined symbol:foo<int>::value.
这是一个 Clang 错误。不管怎样,它works well适用于 Clang HEAD 7.0.0。
关于c++ - 具有模板特化的 constexpr 数组成员 : inconsistent behavior cross compilers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48361845/
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
我的瘦服务器配置了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_”……这
对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs
我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我正在使用Mandrill的RubyAPIGem并使用以下简单的测试模板:testastic按照Heroku指南中的示例,我有以下Ruby代码:require'mandrill'm=Mandrill::API.newrendered=m.templates.render'test-template',[{:header=>'someheadertext',:main_section=>'Themaincontentblock',:footer=>'asdf'}]mail(:to=>"JaysonLane",:subject=>"TestEmail")do|format|format.h
所以这可能有点令人困惑,但请耐心等待。简而言之,我想遍历具有特定键值的所有属性,然后如果值不为空,则将它们插入到模板中。这是我的代码:属性:#===DefaultfileConfigurations#default['elasticsearch']['default']['ES_USER']=''default['elasticsearch']['default']['ES_GROUP']=''default['elasticsearch']['default']['ES_HEAP_SIZE']=''default['elasticsearch']['default']['MAX_OP
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我从用户Hirolau那里找到了这段代码:defsum_to_n?(a,n)a.combination(2).find{|x,y|x+y==n}enda=[1,2,3,4,5]sum_to_n?(a,9)#=>[4,5]sum_to_n?(a,11)#=>nil我如何知道何时可以将两个参数发送到预定义方法(如find)?我不清楚,因为有时它不起作用。这是重新定义的东西吗? 最佳答案 如果您查看Enumerable#find的文档,您会发现它只接受一个block参数。您可以将它发送两次的原因是因为Ruby可以方便地让您根据它的“并行赋