当我尝试编译时,
#include <iostream>
struct K{
const static int a = 5;
};
int main(){
K k;
std::cout << std::min(k.a, 7);
}
我得到关注。双方gcc
并clang
给出了类似的错误:
/tmp/x-54e820.o: In function `main':
x.cc:(.text+0xa): undefined reference to `K::a'
clang-3.7: error: linker command failed with exit code 1 (use -v to see invocation)
如果我按照以下说明进行编译,则不会出现任何问题。这与std::min
写作方式有关吗?
#include <iostream>
struct K{
const static int a = 5;
};
int main(){
K k;
std::cout << std::min((int) k.a, 7); // <= here is the change!!!
}
避免错误的另一种方法是,如果我自己做min()
:
template <class T>
T min(T const a, T const b){
return a < b ? a : b;
}
类似C的预处理器MIN
也可以正常工作。
std::min
通过引用接受参数。将引用绑定到对象意味着该对象已被使用([basic.def.odr] / 2中有一个代码示例,与您的示例几乎相同)。
但是,在这种(int)k.a
情况下,它k.a
是不可使用的;因为它正在执行从左值到右值的转换,从而产生一个常数表达式。(这里也有其他一些条件,但是您的代码还可以)。
如果一个对象被过量使用,那么它必须有一个确切的定义。无需诊断即可违反此规则。因此,第一种情况可能会或可能不会被接受;第二种情况必须接受。
在您自己的版本中min
,它按值接受参数,这与(int)k.a
情况类似-唯一的操作k.a
是进行rvalue转换以初始化your的参数min
。
您可以在C ++标准草案的[basic.def.odr]部分中阅读有关odr使用的全套规则。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句