我是否认为只应在编译时评估此函数,或者是否存在运行时成本?
template <typename T>
size_t constexpr CompID() {
return typeid(T).hash_code();
}
struct Foo {};
int main(int argc, const char * argv[]) {
size_t foo = CompID<Foo>();
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我有一个像:
enum E
{
TYPE_FLOAT,
TYPE_CHAR,
TYPE_INT
}
Run Code Online (Sandbox Code Playgroud)
我想创建一个编译时映射,以获得适合类型的E:
GetE<float> // returns TYPE_FLOAT
GetE<char> // returns TYPE_CHAR
GetE<int> // returns TYPE_INT
Run Code Online (Sandbox Code Playgroud)
我想到了:
template<class T> struct GetE;
template<> struct GetE<float> { static constexpr E type = TYPE_FLOAT; };
template<> struct GetE<char> { static constexpr E type = TYPE_CHAR; };
template<> struct GetE<int> { static constexpr E type = TYPE_INT; };
Run Code Online (Sandbox Code Playgroud)
但我得到的错误如下:
undefined reference to `GetE<int>::type'
Run Code Online (Sandbox Code Playgroud)
什么是最好的方法呢?为什么错误呢?
当我想要一个静态指针作为我需要constexpr进行初始化的类的成员时nullptr.
class Application {
private:
constexpr static Application* app = nullptr;
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释我为什么需要这样做吗?我无法找到为什么静态变量必须在编译时存在的确切原因.
在下面,static constexpr成员L在类中初始化A,然后通过值或(通用)引用传递.后者在Clang中失败但在GCC中失败,并且成员/非成员函数的行为略有不同.更详细:
#include <iostream>
using namespace std;
struct A
{
static constexpr size_t L = 4;
template <typename T>
void member_ref(T&& x) { cout << std::forward<T>(x) << endl; }
template <typename T>
void member_val(T x) { cout << x << endl; }
};
template <typename T>
void ref(T&& x) { cout << std::forward<T>(x) << endl; }
template <typename T>
void val(T x) { cout << x << endl; }
int main ()
{
A().member_ref(A::L); …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用C++自定义文字.我发现奇怪的是,当我将类型从long double类型更改为double或者尝试通过引用传递时,下面的简单函数停止工作.
起初我认为它与使用有关,constexpr但似乎并非如此,因为如果它们不在,这两种工作都很好operator "",并且constexpr从中operator ""删除不会删除错误.
这些经过深思熟虑的决策是在语言设计中,还是仅仅是我的编译器(gcc 4.8.2)无法处理的细微差别?
// Conversion function, works fine with both long double and
// double, and with or without pass by reference.
constexpr long double to_deg (const long double& deg)
{
return deg*M_PI/180.0;
}
// Custom literal with long double types and pass by value,
// works fine.
constexpr long double operator "" _deg (long double deg)
{
return deg*M_PI/180.0;
}
// Custom literal …Run Code Online (Sandbox Code Playgroud) 是否有可能推导出c ++ 17函数的模板值(而不是类型)?
函数foo:
template<int I>
int foo()
{
return (I);
}
Run Code Online (Sandbox Code Playgroud)
可以通过以下方式调用
foo<5>();
Run Code Online (Sandbox Code Playgroud)
并将返回5.
模板类型可以通过函数参数的类型推断出来.是否可以以某种方式对模板值执行相同操作?例如:
template<int I = x>
int bar(const int x)
{
return (I);
}
Run Code Online (Sandbox Code Playgroud)
这显然不会起作用(因为x在声明之前需要一个),但是可能会有一些C++ 17技巧可以实现这一点吗?
我想用它来设置常量表达式函数参数.
这就是我想要做的; 发布整个代码,因为它不会太长,也是为了演示我正在尝试解决的具体任务.基本上,我需要一种方法来从参数包中按索引迭代值(索引部分很重要,即使在本例中不需要).
#include <iostream>
#include <tuple>
#include <type_traits>
template <int First, int Last, typename Functor>
constexpr void static_for(Functor&& f)
{
if constexpr (First < Last)
{
f(std::integral_constant<int, First>{});
static_for<First + 1, Last, Functor>(std::forward<Functor>(f));
}
}
template <size_t index, typename... Args>
auto value_by_index(Args&&... args) noexcept {
return std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...));
}
template <typename... ValueTypes>
void traverse(ValueTypes... values)
{
static_for<0, sizeof...(ValueTypes)>([&](int i) {
auto v = value_by_index<static_cast<size_t>(i), ValueTypes...>(values...);
std::cout << v << std::endl;
});
}
int main()
{
traverse(0.0f, 1, 3.33, "str");
return 0; …Run Code Online (Sandbox Code Playgroud) 一些代码:
constexpr int sum(int a, int b) {
return a + b;
}
int main() {
int a = sum(4, 5);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我使用编译此代码,clang-9但int a在编译时不评估main函数的值。如果我使用constexpr int aclang在编译时对其进行评估,但我无法在运行时更改此变量。
但是在编译时gcc-7.1评估的值int a。
为什么会这样呢?如何解决?
我无法理解此错误的实质,因此,如果标题更好,请原谅。此代码无法编译:
template <auto v>
struct value_as_type {
using type = decltype(v);
static constexpr type value {v};
constexpr operator type() const {
return v;
}
};
template <int First, int Last, typename Functor>
constexpr void static_for([[maybe_unused]] Functor&& f)
{
if constexpr (First < Last)
{
f(value_as_type<First>{});
static_for<First + 1, Last, Functor>(std::forward<Functor>(f));
}
}
template <class... FieldsSequence>
struct DbRecord
{
private:
static constexpr bool checkAssertions()
{
static_assert(sizeof...(FieldsSequence) > 0);
static_for<1, sizeof...(FieldsSequence)>([](auto&& index) {
constexpr int i = index;
static_assert(i > 0 && …Run Code Online (Sandbox Code Playgroud) c++ rvalue-reference constexpr pass-by-rvalue-reference c++17