我想检查某个模板专业化是否存在,其中一般情况没有定义.
鉴于:
template <typename T> struct A; // general definition not defined
template <> struct A<int> {}; // specialization defined for int
Run Code Online (Sandbox Code Playgroud)
我想定义一个像这样的结构:
template <typename T>
struct IsDefined
{
static const bool value = ???; // true if A<T> exist, false if it does not
};
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点(理想情况下没有C++ 11)?
谢谢
我有一个可变函数动物园,它带有N个参数,其中N在编译时是已知的(它是包含该函数的类的模板参数).
template <int N>
struct B
{
template <typename... Args>
static void zoo(Args... args)
{
static_assert(size of...(args) == N, "");
// do something
}
};
Run Code Online (Sandbox Code Playgroud)
我有另一个可变函数foo,它接受M个参数,其中M> N并且在编译时是已知的(它是包含该函数的类的模板参数).我有一个静态index_array,其中包含我要传递给zoo的foo参数的索引.
从foo的主体我想调用zoo传递foo参数的选定子集.
做这个的最好方式是什么?理想情况下实现完美的内联,即所有内容都只编译成一条没有函数指针间接指令的指令?
template<int...I>
struct indices
{
static constexpr int N = sizeof...(I);
};
template <int M, typename...X>
struct A
{
// here I am simplifying, in reality IS will be built at compile time based on X
typedef indices<0,2,3> …Run Code Online (Sandbox Code Playgroud) 我有一个共享库,导出一元函数,如:
extern "C" void foo(int);
extern "C" void zoo(double);
Run Code Online (Sandbox Code Playgroud)
该库由没有C++ 11支持的编译器使用.我想从函数名称中在结构中静态推断函数类型.
我可以写:
template <typename T, void(*)(T)> struct A{ typedef T arg_t; };
Run Code Online (Sandbox Code Playgroud)
为此,我必须T在实例化模板时明确指定类型,即我必须编写
A<int, &foo>
Run Code Online (Sandbox Code Playgroud)
而不仅仅是
A<&foo>
Run Code Online (Sandbox Code Playgroud)
鉴于此信息嵌入在指针类型中,有没有一种方法可以静态提取?
gcc无法编译下面的代码,而clang编译正常。我无法控制宏PORTB,因为它在 3rd 方库 ( avr) 中。
这是一个gcc错误吗?我怎样才能解决它gcc?作为一种解决方法,可以创建一个从 PORTB 中提取数值的预处理器宏?
请注意,这个问题与我之前的问题相似,但不完全相同。它也不同于这个问题,开发者可以灵活地改变赋值的 rhs,从而避免reinterpret_cast.
#include <iostream>
#include <cstdint>
#define PORTB (*(volatile uint8_t *)((0x05) + 0x20))
struct PortB {
static const uintptr_t port = reinterpret_cast<uintptr_t>(&PORTB);
};
int main() {
std::cout << PortB::port << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud) avr-gcc为一个8位微控制器编译一些测试代码
const uint32_t N = 65537;
uint8_t values[N];
Run Code Online (Sandbox Code Playgroud)
我得到了以下编译警告(默认情况下应该是一个错误,真的)
warning: conversion from 'long unsigned int' to 'unsigned int' changes value from '65537' to '1' [-Woverflow]
uint8_t values[N];
Run Code Online (Sandbox Code Playgroud)
请注意,编译此目标时,sizeof(int)为2.
所以看来,在一个数组大小不能超过一个unsigned int.
我对么?这是GCC特定的还是某些C或C++标准的一部分?
在有人评论说8位微控制器通常没有足够的内存来容纳如此大的阵列之前,让我只是期待说这不是重点.
当模板类继承自另一个模板类时,必须再次重新定义基类中的typedef(即它们不会自动继承),并且需要限定基类中的函数调用.这是为什么?这不是明确的吗?
因此,如果我有20个模板类,都定义了相同的typedef,我无法引入包含这些定义的基类并从中继承,因为我必须在每个类中重新定义typedef,这会破坏目的.这使得源代码不必要地冗长.
我可以看到这个已经在这个问题中讨论过,但我不明白这个评论
C++名称查找规则指定仅在模板化基类中搜索名称(如果它取决于模板参数(如果它是"依赖名称")).如果名称不依赖于模板参数,则不会在那里搜索.
这是什么原因?对我来说完全是无稽之谈.
也许,下面的代码片段会更好地说明我的问题:
#include <iostream>
template <unsigned N, typename T>
struct A
{
typedef T U;
static void foo(T x) { std::cout << N + x << "\n"; }
};
template <unsigned N, typename T>
struct B : public A<N, T>
{
// Why do I have to redeclare U? Isn't is unambiguous already?
typedef typename A<N, T>::U U;
// why do I have to specify B::? Isn't it unambiguous already?
static void zoo(U x) …Run Code Online (Sandbox Code Playgroud) 在下面的小程序中,我展示了我目前用于提取类的模板参数并通过递归辅助函数迭代它的解决方案.
我想知道是否有更简洁的方法来做,正如我在下面的评论中的伪代码中解释的那样.
template <int...Is> struct Pack {};
template <int I> struct B
{
static void foo() { std::cout << I << "\n"; }
};
// recursive helper function, also used to extract the parameter pack arguments
template <int I, int...Is>
void foo_helper( Pack<I, Is...>&& )
{
B<I>::foo();
foo_helper( Pack<Is...>{} );
}
// terminate recursion
void foo_helper( Pack<>&& ) {}
struct A
{
typedef Pack<1,3,5> ints;
static void foo()
{
// this is what I do
foo_helper(ints{});
// this is what …Run Code Online (Sandbox Code Playgroud) 我有数据结构:
template <int...I> struct index {};
template <typename...T> struct data {};
template <int I, int J> struct X
{
static constexpr int i = I;
static constexpr int j = J;
};
typedef data< X<0,4>, X<1,2>, X<2,1>, X<1,6>, X<1,3> > data_t;
Run Code Online (Sandbox Code Playgroud)
如果数据不包含重复项且索引J很小,则在0-31范围内.
我想创建一个静态索引,其中包含索引I等于某个给定值(例如I = 1)的所有X的数据中的位置,按索引J排序.这是我觉得困难的"排序"位.
例如,我想实现一个类build_index,以便:
typedef build_index<1,data>::type_t index_t;
Run Code Online (Sandbox Code Playgroud)
生成相同的:
typedef index<1, 4, 3> index_t;
Run Code Online (Sandbox Code Playgroud)
它反映了由J:X(1,2)在数据(1),X(1,3)在数据(4),X(1,6)处排序的元素X(1,J)的数据中的位置.数据(3)
我宁愿不使用STL,因为它不适用于gcc-avr,尽管我可以移植选定的片段.
设V是属于域D的元素数组(例如整数)
V = {v1, v2, ..., vN}
Run Code Online (Sandbox Code Playgroud)
设f(x,y)是[DxD] - > D中定义的二元算子z = f(x,y).
f是联想和可交换的.
f不支持其完整域上的逆,即如果结果z和参数x或y中的一个已知,则不总是可以获得另一个参数.
给定一对有序索引(i,j),运算符g(i,j)被定义为用运算符f获得的子数组{vi,...,vj}的减少.
例如,如果f是乘法运算符,即f(x,y)= x*y,则
g(2,5) = v2 * v3 * v4 * v5
Run Code Online (Sandbox Code Playgroud)
我需要在一大组对(i,j)上计算函数g,它们涉及向量V的重叠元素.
我想利用运算符f的关联性来使用运算符f的最小可能应用数来执行该计算,因为f在计算上非常昂贵.
例如,坚持上面的例子,其中f是整数乘法,给定一个包含5个条目的数组V和索引对(1,3),(2,4),(2,5),(1,4) ,我可以用6个乘法计算所有对:
V={1, 2, 0, 3, 5}
1. V12 = V1 * V2
2. V13 = V12 * V3 // pair (1,3)
3. V14 = V13 * V4 // pair (1,3)
4. V23 = V2 * V3
5. V24 = V23 * V4 // pair (2,4)
6. V25 = V24 * …Run Code Online (Sandbox Code Playgroud) 在基于 CAS 的循环中,例如下面的循环,使用暂停对 x86 有益吗?
void atomicLeftShift(atomic<int>& var, int shiftBy)
{
While(true) {
int oldVal = var;
int newVal = oldVal << shiftBy;
if(var.compare_exchange_weak(oldVal, newVal));
break;
else
_mm_pause();
}
}
Run Code Online (Sandbox Code Playgroud)