我试图在编译时确定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属性创建结构的成员而不是静态会导致编译器错误(请参阅下文).这是为什么?对于单个常量值,我将在内存中使用此值,直到程序终止而不仅仅是struct的范围?我应该回去使用宏吗?
struct foo
{
constexpr int n = 10;
// ...
};
error: non-static data member cannot be constexpr; did you intend to make it static?
Run Code Online (Sandbox Code Playgroud) 我有以下C++ 11代码(简化版):
struct Info
{
const char * name;
int version;
};
class Base
{
public:
const Info info;
Base (Info info) : info (info) {}
};
class Derived : public Base
{
public:
static constexpr Info info = {"Foobar", 2};
Derived () : Base (info) {}
};
int main ()
{
static Derived derived;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
GCC 4.9.1编译并链接此代码.另一方面,Clang 3.5.0抱怨未定义的引用:
/tmp/test-109c5c.o: In function `main':
test.cc:(.text+0x1c): undefined reference to `Derived::info'
test.cc:(.text+0x22): undefined reference to `Derived::info'
clang: error: linker command failed …Run Code Online (Sandbox Code Playgroud) 根据: constexpr静态数据成员给出未定义的引用错误 静态constexpr类成员必须满足两个要求:
template <typename Tp>
struct wrapper {
static constexpr Tp value{}; // 1
};
template<typename Tp>
constexpr Tp wrapper<Tp>::value; // 2
struct foo {
};
int main() {
auto const& x = wrapper<foo>::value;
(void)x;
}
Run Code Online (Sandbox Code Playgroud)
如果我改变1.统一初始化
template <typename Tp>
struct wrapper {
static constexpr auto value = Tp{}; // uniform initialization
};
template<typename Tp>
constexpr Tp wrapper<Tp>::value;
Run Code Online (Sandbox Code Playgroud)
编译器抱怨冲突的声明:
$ g++ prog.cc -Wall -Wextra -std=c++1z -pedantic
prog.cc:7:31: error: conflicting declaration 'constexpr const Tp wrapper<Tp>::value' constexpr Tp wrapper<Tp>::value; …Run Code Online (Sandbox Code Playgroud) 在编写我的初始问题时,如果这是可能的,我偶然发现了与定义类相同类型的静态constexpr成员的问题,这很清楚地回答了我的干净解决方案无法用C++ 11实现.
但后来我提出了这个与原始海报非常接近的代码,我希望实现:
class MyEnum
{
public:
constexpr MyEnum() : m_null(true), m_value(0) { }
constexpr MyEnum(const unsigned int v) : m_null(false), m_value(v) { }
constexpr operator unsigned int() const { return m_value; }
static constexpr const MyEnum one() { return MyEnum(1); }
private:
bool m_null;
unsigned int m_value;
};
Run Code Online (Sandbox Code Playgroud)
所以我在重述我的问题:为什么one编译的解决方案可以像你期望的那样使用,但是下面的解决方案会给出使用不完整类的错误?
class MyEnum
{
public:
// snip...
static constexpr const MyEnum two = MyEnum(2);
static constexpr const MyEnum three = 3;
// snip...
}
Run Code Online (Sandbox Code Playgroud) 根据我的理解,constexpr函数可以在编译时和运行时执行,具体取决于整个评估是否可以在编译时完成.
但是,您不能重载此函数以使运行时和编译时对应.
所以我的问题是,如何在运行时断言中确保运行时函数的执行与我的static_assert一起传递有效参数?
#include <iostream>
#include <string>
void foo(int& k) { std::cout << "int&\n"; }
void foo(int&& k) { std::cout << "int&&\n"; }
void foo(const int& k) { std::cout << "const int&\n"; }
void foo(const int&& k) { std::cout << "const int&&\n"; }
int main() {
static constexpr int k = 1;
foo(k);
foo(1);
}
Run Code Online (Sandbox Code Playgroud)
输出是:
const int&
int&&
Run Code Online (Sandbox Code Playgroud)
constexpr变量到底是什么?foo给出的重载const int&.
编辑:继续使用constexpr推断为const T&;
为什么类范围的constexpr无法传递给采用通用引用的函数?!
#include <type_traits>
template <typename T>
void goo(T&& k) {
static_assert(std::is_same<decltype(k), const int&>::value, "k …Run Code Online (Sandbox Code Playgroud) 当我使用scons编写一些程序时,会发生类似的错误,
错误:未知类型名称'constexpr'
错误:预期的不合格ID
我已经安装了xcode和xquartz最新版本。这是我的Mac clang版本
Apple LLVM版本8.1.0(clang-802.0.42)目标:x86_64-apple-darwin16.6.0线程模型:posix InstalledDir:/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
而且,我附上我的整个错误日志,以防万一。
/Users/jeon.hk/Documents/geant4/geant4.10.3-install/bin/../include/Geant4/CLHEP/Units/SystemOfUnits.h:54:10: error: unknown type name 'constexpr'
static constexpr double pi = 3.1415;
^
/Users/jeon.hk/Documents/geant4/geant4.10.3-install/bin/../include/Geant4/CLHEP/Units/SystemOfUnits.h:54:20: error: expected unqualified-id
static constexpr double pi = 3.1415;
^
/Users/jeon.hk/Documents/geant4/geant4.10.3-install/bin/../include/Geant4/CLHEP/Units/SystemOfUnits.h:55:10: error: unknown type name 'constexpr'
static constexpr double twopi = 2*pi;
^
/Users/jeon.hk/Documents/geant4/geant4.10.3-install/bin/../include/Geant4/CLHEP/Units/SystemOfUnits.h:55:20: error: expected unqualified-id
static constexpr double twopi = 2*pi;
^
/Users/jeon.hk/Documents/geant4/geant4.10.3-install/bin/../include/Geant4/CLHEP/Units/SystemOfUnits.h:56:10: error: unknown type name 'constexpr'
static constexpr double halfpi = pi/2;
^
/Users/jeon.hk/Documents/geant4/geant4.10.3-install/bin/../include/Geant4/CLHEP/Units/SystemOfUnits.h:56:20: error: expected unqualified-id
static constexpr double halfpi = pi/2; …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
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!"不要超出功能范围......
我想将"数组"转换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 ×10
c++ ×9
c++11 ×8
c++14 ×2
assert ×1
assertions ×1
c-strings ×1
clang ×1
overloading ×1
plugins ×1
templates ×1
validation ×1