我有以下代码
class A
{
private:
class B
{
public:
void f()
{
printf("Test");
}
};
public:
B g()
{
return B();
}
};
int main()
{
A a;
A::B b; // Compilation error C2248
A::B b1 = a.g(); //Compilation error C2248
auto b2 = a.g(); // OK
a.g(); // OK
b2.f(); // OK. Output is "Test"
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我有A类和私有嵌套类B.不使用auto我不能在A之外创建A :: B的实例,但是我可以使用auto.有人可以解释这里有什么问题吗?我使用VC++ 12.0,13.0,14.0(总是相同的行为)
我不明白这段代码是如何工作的。谁能告诉我一点。我非常确定“参数包应该是最后一个参数”
void foo(auto&&...args1, auto&&... args2, auto&&... args3) {
std::cout << "args1:\n", ((std::cout << args1 << " "), ...);
std::cout << "args2:\n", ((std::cout << args2 << " "), ...);
std::cout << "args3:\n", ((std::cout << args3 << " "), ...);
}
int main(int argc, char** argv)
{
foo(1,2,3,4,5,6);
}
Run Code Online (Sandbox Code Playgroud)
如果允许,我如何拆分arg1、args2和args3?
编译器 (g++-11) 假定除 args3 之外的所有参数包均为空,因此输出为
args1:
args2:
args3:
1 2 3 4 5 6
Run Code Online (Sandbox Code Playgroud) 我期望这段代码创建 10 个元素向量,每个向量构造为A{1, 2, 3.0},但实际上输出是1
#include <iostream>
#include <vector>
struct A {
int a{0};
int b{0};
double c{0.0};
};
template<typename T, size_t... Ns>
auto create_array(std::index_sequence<Ns...>, auto&&... args) {
return std::vector<T> {
([&](...){ return std::forward<T>(T{args...}); }(Ns), ...)
};
}
template<typename T, size_t N>
auto create_array(auto&&... args) {
return create_array<T>(std::make_index_sequence<N>{}, std::forward<decltype(args)>(args)...);
}
int main() {
std::cout << create_array<A, 10>(1,2,3.0).size() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
怎么会发生这种事,为什么没有正确展开?这里有什么问题吗?我特别想要这条线
([&](...){ return std::forward<T>(T{args...}); }(Ns), ...)
Run Code Online (Sandbox Code Playgroud)
成为
[&](...){ return std::forward<T>(T{args...}); }(0),
[&](...){ return std::forward<T>(T{args...}); }(1),
[&](...){ return …Run Code Online (Sandbox Code Playgroud) 我试图弄清楚如何使用C ++ 17折叠表达式仅折叠可变参数模板包的一部分。假设我想创建一个编译时的“分隔字符串”,例如"str1_str2_str3_....."
使用这样的代码可以很容易地做到这一点(仅作为示例):
std::string result;
template<class... Strings>
ConcatString(Strings&... strs)
{
(ConcatString(strs), ...);
}
template <class String>
void ConcatString(String& str)
{
result += str + "_"
}
Run Code Online (Sandbox Code Playgroud)
然后我们可以像这样执行它
std::string s1 = "s1", s2 = "s2", s3 = "s3";
ConcatString(s1, s2, s3);
// result == "s1_s2_s3_"
Run Code Online (Sandbox Code Playgroud)
如您所见,最后一个定界符存在问题。没有运行时检查,有什么办法可以避免此问题?我可以想象的一种解决方案是仅折叠(N-1)个arg,并“手动”连接最后一个。
愚蠢的问题。谁能向我解释一下这段代码是如何工作的?(从这里https://alexpolt.github.io/type-loophole.html)
#include <string>
#include <type_traits>
template<int N> struct tag{};
template<typename T, int N>
struct loophole_t {
friend auto loophole(tag<N>) { return T{}; };
};
auto loophole(tag<0>);
int main() {
sizeof( loophole_t<std::string, 0> );
static_assert(std::is_same< std::string, decltype( loophole(tag<0>{}) ) >::value);
}
Run Code Online (Sandbox Code Playgroud)
看起来sizeof( loophole_t<std::string, 0> );影响编译器全局状态。我的意思是如果我们删除这条线static_asserts失败。在 C++ 中允许吗?
更新:刚刚意识到这取决于编译器甚至编译器版本。适用于任何 GCC >=8(可能也适用于旧版本)。不能用 clang >= 10 编译,但在 clang 7.0 下工作正常
所以我想说我真正的问题是编译器错误还是标准行为?
受到这个问题的启发
有了这个代码
#include <string>
template<class T>
struct A {
template <typename U> using NewA = A<U>;
constexpr A(T const& t){}
constexpr auto f() const {
return NewA{"bye"};
}
};
A(const char*) -> A<std::string>;
int main() {
A{"hello"}.f();
}
Run Code Online (Sandbox Code Playgroud)
GCC 13.1 生成大量无用代码(最显着的是调用 std::string 构造函数/析构函数以及其他一些东西)
main:
sub rsp, 72
mov edx, OFFSET FLAT:.LC1+5
mov esi, OFFSET FLAT:.LC1
lea rax, [rsp+16]
mov rdi, rsp
mov QWORD PTR [rsp], rax
call void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) [clone .isra.0] …Run Code Online (Sandbox Code Playgroud) 我需要一些来自c ++代码的外部程序调用的帮助.
我必须javap.exe多次(可能超过100)从我的程序中调用(来自JDK包),但调用system("javap.exe some_parameters")非常慢.对于一组参数,它的工作非常好,但重复的调用是system()不可接受的.我认为这只是因为访问硬盘和应用程序运行的成本(但我不确定).
我能做些什么才能获得更好的表现?我可以"保存javap.exe在RAM中"并"直接"调用它.或者可能有人知道我怎么能获得java级的描述和方法签名javap.exe?
我正在看这个C++ 讲座(俄语)。16:10 左右,讲师提出了一个悬而未决的问题:
有这个代码:
int* foo()
{
volatile auto a = nullptr;
int* b = a;
return b;
}
int main()
{}
Run Code Online (Sandbox Code Playgroud)
Clang为(-Ofast)生成以下程序集foo
mov qword ptr [rsp - 8], 0 # volatile auto a = nullptr;
xor eax, eax
ret
Run Code Online (Sandbox Code Playgroud)
这意味着编译器假设读取没有副作用,a并且基本上删除了int* b = a;部分代码。
另一方面,GCC生成了一些不同的代码
mov QWORD PTR [rsp-8], 0 # volatile auto a = nullptr;
mov rax, QWORD PTR [rsp-8] # int* b = a;
xor eax, eax
ret …Run Code Online (Sandbox Code Playgroud) 以下程序是否格式错误?如果是这样,这里进行诊断有什么问题吗?
template <typename T> struct A { int a{sizeof(T)}; };
int main() { sizeof(A<void>); }
Run Code Online (Sandbox Code Playgroud)
Clang 为该代码生成以下专业化 ( clang++ -std=c++20 -Xclang -ast-print -fsyntax-only main.cpp):
template <typename T> struct A {
int a {sizeof(T)};
};
template<> struct A<void> {
int a;
};
int main() {
sizeof(A<void>);
}
Run Code Online (Sandbox Code Playgroud) 我可以通过检查const integere参数来选择模板方法吗?
我需要这样的东西
template <size_t N <= 90>
void f1(){....}
template <size_t N > 90>
void f2(){....}
Run Code Online (Sandbox Code Playgroud)
我的解决方案是
template <size_t N>
void f()
{
N <= 90 ? f1(N) : f2(N);
}
Run Code Online (Sandbox Code Playgroud)
但我认为这个approch不是很好因为f()将始终在运行时调用(可能不是编译器非常聪明).这样想的最佳方法是什么?