最小例子:
#include <cstddef>
struct B
{
constexpr static const size_t MAX = 10;
};
struct D : B
{
constexpr static const size_t MAX = 20;
};
void use(const B& v)
{
static_assert(v.MAX == 10, "");
}
template<typename X>
void use2(X&& v)
{
static_assert(v.template MAX == 20, "");
}
int main ()
{
D d;
static_assert(d.MAX == 20, "");
use(d);
use2(d);
return 0;
}
GCC(v5.4 ... v7.3):编译好(任何级别的优化和-Wall -Wextra -pedantic) ICC / MSVC:编译好(在godbolt.org上尝试各种版本)
CLANG(v4 ... v6):错误:static_assert表达式不是整数常量表达式 static_assert(v.MAX == 10,“”);
编辑(改写问题):在我看来,clang的行为是最不令人惊讶的(或更直观)。鉴于它是唯一没有编译上述代码的编译器,我想了解这两种行为中的哪一种是正确的以及为什么?
编辑2:
通过添加模板函数判断,gcc看起来使用参数的声明类型,并确定使用哪个constexpr成员,而不管传入的是什么。
如果通过值,clang也会将MAX评估为常量表达式。在这种情况下,很明显为什么v.MAX == 10对于非模板化函数的所有编译器都是正确的。
编辑3(甚至更短的版本): 哪个仍然无法在clang上编译
#include <cstddef>
struct B
{
constexpr static const size_t MAX = 10;
};
void use(const B& v)
{
static_assert(v.MAX == 10, "");
}
template<typename X>
void use2(X&& v)
{
static_assert(v.template MAX == 10, "");
}
int main ()
{
B v;
static_assert(v.MAX == 10, "");
use(v);
use2(v);
return 0;
}
答案 0 :(得分:2)
Clang是对的。
import os, subprocess
fileToRemove = '/home/user/fileName';
if os.path.isfile(fileToRemove):
subprocess.run(['rm', '-f', '--preserve-root', fileToRemove]
subprocess.run(['safe-rm', '-f', fileToRemove]
评估v.MAX == 10
,这是没有先前初始化的引用。在常量表达式中不允许这样做。
请注意,即使v
是静态成员,MAX
评估期间仍会评估v
。
您可以使用班级类型访问v.MAX
以避免评估MAX
,例如
v