在编译时搜索了一种检查endianess的方法后,我提出了以下解决方案:
static const int a{1};
constexpr bool is_big_endian()
{
return *((char*)&(a)) == 1;
}
Run Code Online (Sandbox Code Playgroud)
GCC仅在需要constexpr的某些上下文中接受此代码:
int b[is_big_endian() ? 12 : 25]; //works
std::array<int, testendian() ? 12 : 25> c; //fails
Run Code Online (Sandbox Code Playgroud)
对于第二种情况,GCC说error: accessing value of ‘a’ through a ‘char’ glvalue in a constant expression
.我无法在禁止此类事件的标准中找到任何内容.也许有人可以澄清GCC在哪种情况下是正确的?
我有以下类模板:
template<class T, unsigned N>
class MyClass;
Run Code Online (Sandbox Code Playgroud)
其中T
是某种类型的,N
-多个组件.可以使用MyClass{a1, a2, a3}
参数数量等于的位置初始化类N
.
我想添加一个符合以下要求的成员函数模板(让我们命名foo
)MyClass
:
T2
(即template<class T2> void foo(..)
)MyClass<T,N>
,但不是更少而不是更多.违反此规则会导致编译时错误.T2
从参数的类型推导出来.即我想要无需打字或每次都可以打电话foo({a1, a2, a3})
或打电话.foo(a1, a2, a3)
<double>
MyClass<double,N>
有没有办法实现这个功能,以满足上述要求?
我已经考虑过和/或尝试过以下解决方案:
1)显而易见的一个:
...
template<class T2>
void foo(MyClass<T2, N> arg);
...
a.foo({1,2,3}); //compile-time error
Run Code Online (Sandbox Code Playgroud)
原则上不能工作,因为支撑的初始化列表是非推导的上下文,因此它们不能推导出任何类型.这很不幸,如果有效,我会很高兴.
2)initializer_list
原则上不能工作,因为它无法在编译时检查参数的数量.
3)Variadic模板魔术
像下面的功能一样整洁:
template<class...T2, class std::enable_if<sizeof...(T2) == N, int>::type = 0>
void foo(T2... …
Run Code Online (Sandbox Code Playgroud) 我有一个类模板,我想介绍几个模板特化.那些模板特化与某些现有类型相同.从概念上讲,我想将它们实现为别名/ typedef.
以下示例代码应显示我想要执行的操作:
template<class T> class Common {
/// general implementation
};
class TypeZ;
template<> class Common<Type1> = TypeZ; // <<< how to do this?
template<> class Common<Type2> = TypeZ;
template<> class Common<Type3> = TypeZ;
Run Code Online (Sandbox Code Playgroud)
在C++(或C++ 11)中,上述内容是否可行?如果我不必实现Common<...>
作为继承的类TypeZ
- 那将是很好的- 实际代码比上面显示的更复杂,并且继承TypeZ
在那里不是一个好主意.
我有以下代码:
#include <cstdio>
template<class Fun, class... Args>
void foo(Fun f, Args... args)
{
f(args...);
}
int main()
{
int a = 2;
int b = 1000;
foo([](int &b, int a){ b = a; }, b, a);
std::printf("%d\n", b);
}
Run Code Online (Sandbox Code Playgroud)
目前它打印1000
,即b
在某处丢失的新价值.我想这是因为foo
通过值传递参数包中的参数.我该如何解决这个问题?
该标准的20.8.2美元描述了INVOKE工具,该工具主要用于描述如何使用标准库中的可变参数列表调用可调用对象:
定义INVOKE(f,t1,t2,...,tN)如下:
-
(t1.*f)(t2, ..., tN)
当f是指向类T的成员函数的指针时,t1是类型为T的对象或对类型为T的对象的引用或对从T派生的类型的对象的引用;-
((*t1).*f)(t2, ..., tN)
当f是指向类T的成员函数的指针时,t1不是前一项中描述的类型之一;-
t1.*f
当N == 1并且f是指向类T的成员数据的指针时,t1是类型T的对象或对类型T的对象的引用或对从T派生的类型的对象的引用;-
(*t1).*f
当N == 1且f是指向类T的成员数据的指针时,t1不是前一项中描述的类型之一;-
f(t1, t2, ..., tN)
在所有其他情况下.
第三和第四项是什么?据我所知,f
即使f
可以调用,他们也不会打电话.他们的用户案例是什么?也许这是标准中的拼写错误并且*f()
是有意的吗?
有关背景,请参阅此问题.
基本上,我有一个类的以下定义
class MyClass {
virtual int foo4(double, int);
};
Run Code Online (Sandbox Code Playgroud)
有没有办法指示编译器生成两个可以解析的符号foo4
?也就是说,如果可执行文件要求动态链接器解析_ZN7MyClass4foo4Edi
(符号for MyClass::foo4(double, int)
)和其他一些符号(比方说_ZN7MyClass9reserved1Ev
,符号MyClass::reserved1()
),我希望动态链接器将两者解析为&MyClass::foo4(double, int)
.我在Linux上使用相当现代的GCC.
是否可以在Doxygen文档中对函数参数进行分组,以便我不必复制注释?例如,我想要类似的东西:
/**
<...>
@param {{a, b}} <long documentation>
*/
Run Code Online (Sandbox Code Playgroud)
氧气输出:
<...>
Parameters:
a,b - <long documentation>
Run Code Online (Sandbox Code Playgroud)