我试图在编译时确定a std::initializer_list中的所有值是否唯一.我找到了一个解决方案,以确定列表的大小,但无法将其应用于内容.我已尝试使用自由函数和构造函数,但这两种方法都导致GCC 4.7.2出现以下错误.
错误:静态断言
错误的非常量条件:'begin'不是常量表达式
我意识到std::initializer_list没有声明成员,constexpr但我希望有一个像尺寸验证的解决方案.是否可以使用以下内容在编译时验证内容?
#include <initializer_list>
template<typename InputIterator>
constexpr bool Validate(InputIterator begin, InputIterator end)
{
static_assert(*begin == *end, "begin and end are the same");
// The actual implemetnation is a single line recursive check.
return true;
}
template<typename InputType>
constexpr bool Validate(const std::initializer_list<InputType>& input)
{
// "-1" removed to simplify and eliminate potential cause of error
return Validate(input.begin(), input.end() /* - 1 */);
}
int main()
{
Validate({1, 2, 1});
}
Run Code Online (Sandbox Code Playgroud) 在使用constexpr中的boost数学常量并建议OP使用boost的模板函数constexpr而不是非模板化常量来平息clang错误后,我决定尝试查看哪些条件会重现clang中的错误.让我们尝试复制boost的宏扩展到:
namespace double_constants{ static const double name = 25; }
static constexpr double SEC3 = double_constants::name;
Run Code Online (Sandbox Code Playgroud)
这给出了以下错误(跟随Coliru)
clang++ -std=c++1y -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp:5:25: error: constexpr variable 'SEC3' must be initialized by a constant expression
static constexpr double SEC3 = double_constants::name;
^ ~~~~~~~~~~~~~~~~~~~~~~
main.cpp:5:32: note: read of non-constexpr variable 'name' is not allowed in a constant expression
static constexpr double SEC3 = double_constants::name;
^
main.cpp:3:49: note: declared here
namespace double_constants{ static …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用哈希函数在C中使用基于字符串的开关表达式。我已经能够使用'constexpr'使它与干净的语法一起使用,并且Clang / LLVM转换为C ++,即使代码是C。
但是,将其作为C ++进行编译当然会有一些奇怪的副作用,例如缺少void *隐式转换会变得很尴尬。
因此,问题是如何解决这个难题(为什么不将C11委员会的掌声压在C规范上)
这是我当前的示例代码:
constexpr uint64 cHash(char const* text, uint64 last_value = basis)
{
return *str ? cHash(text+1, (*text ^ last_value) * prime) : last_value;
}
void SwitchFunction(char const* text)
{
switch(Hash(text))
{
case cHash("first"):
break;
case cHash("second"):
break;
case cHash("third"):
break;
default:
break;
}
}
Run Code Online (Sandbox Code Playgroud) 我认为这是不可能的,但我想在放弃之前问你.
我想要像constexpr增量一样的东西.
#include <iostream>
constexpr int inc() {
static int inc = 0;
return inc++;
}
class Foo {
static const int Type = inc();
};
class Foo2 {
static const int Type = inc();
};
int main() {
std::cout << "Foo1 " << Foo1::Type << st::endl;
std::cout << "Foo2 " << Foo2::Type << st::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我想把它称为某些类而不是手动(我使用CRTP),为每个类提供不同的类型,但类型需要是const.无论如何在C++中实现类似的东西?(C++ 17 + TS)
在此网站上,指定:
"constexpr功能必须满足以下要求:
[...]
存在至少一组参数值,使得函数的调用可以是核心常量表达式的计算子表达式(对于构造函数,在常量初始化器中使用就足够了)(自C++ 14起).违反此子弹无需诊断."
粗体陈述的含义是什么?
请考虑以下代码:
constexpr auto f()
{
auto str = "Hello World!";
return str;
}
int main(int argc, char* argv[])
{
static constexpr auto str = f();
std::cout << str << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是正常的,我的编译器没有显示任何警告?它是否定义了行为?我能保证程序会显示"Hello World!"吗?我希望"Hello World!"不要超出功能范围......
我知道模板函数在链接时不会有多个定义,比如在类中定义的成员函数,默认情况下是内联的.此外,constexpr对象具有内部链接,但模板变量具有外部链接(我的意思是在命名空间范围内,在两种情况下都是C++ 14).
关于什么?
template<class T>
constexpr T i_am_odr_safe{};
Run Code Online (Sandbox Code Playgroud)
不i_am_odr_safe具有在C++ 14的外部或内部联动?对于像函数模板这样的多重定义是否安全?
换句话说,是否i_am_odr_safe安全?
我想将"数组"转换bool为整数序列.所以我需要std::array在编译时计算一个.
这是我的代码
#include <array>
template<typename InputIt, typename T >
inline constexpr typename std::iterator_traits<InputIt>::difference_type
count( InputIt first, InputIt last, const T &value ) {
typename std::iterator_traits<InputIt>::difference_type ret = 0;
for (; first != last; ++first) {
if (*first == value) {
ret++;
}
}
return ret;
}
template<bool ..._values>
struct keep_value {
static constexpr std::size_t numberOfValues = sizeof...(_values);
static constexpr bool values[] = {_values...};
static constexpr std::size_t numberToKeep = count(values, values + numberOfValues, true);
static constexpr std::array<std::size_t, …Run Code Online (Sandbox Code Playgroud) c++ template-meta-programming variadic-templates constexpr c++14
为什么constexpr不使用std::cout,但可以使用printf?
#include <iostream>
constexpr void f() { std::cout << ""; } //error
constexpr void g() { printf(""); } //ok
Run Code Online (Sandbox Code Playgroud)
为什么std::cout使用lambdas constexpr?
#include <iostream>
int main () {
auto h = []() constexpr { std::cout << ""; }; //ok
}
Run Code Online (Sandbox Code Playgroud) 当一个类具有constexpr成员函数并且正在constexpr上下文中的l值对象上对该成员函数进行求值时,clang和gcc会不同意结果是否为constexpr值。为什么?有没有既不需要默认可构造性又不需要复制可构造性的解决方法?
当按值传递对象时,两个编译器都将成功编译。
lang版本的树干8、7: static_assert expression is not an integral constant expression
和
Gcc版本trunk,8.1、7.4:编译没有错误
#include <array>
using A = std::array<int, 10>;
void foo(const A& a){
// clang: static_assert expression is not an integral constant expression
static_assert(a.size() > 0, "");
}
void foo2(A a){
// this compiles on both clang and gcc
static_assert(a.size() > 0, "");
}
// Some custom code with the same symptom:
class B{
public:
constexpr int size()const{
return 42;
}
};
void foo3(const B& b){
// clang: static_assert …Run Code Online (Sandbox Code Playgroud)