我有以下代码:
int x = {{}};
Run Code Online (Sandbox Code Playgroud)
这种语法是否符合C++标准?(我对C++ 11及更高版本感兴趣.)
使用最新的编译器时没有问题,但是在一些较旧的编译器(例如GCC 4.8.5)中,它会出现以下错误:
错误:在'int'类型的标量初始值设定项周围括起来
考虑以下代码:
#include <iostream>
struct Foo {
void work() { std::cout << "foo" << std::endl; }
};
typedef void function_type(void *arg);
template <typename T>
void function(void *arg)
{
auto &t = *reinterpret_cast<T*>(arg);
t.work();
}
void call_function(function_type *fn, void *arg)
{
fn(arg);
}
int main()
{
Foo foo;
call_function(&function<Foo>, &foo);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果 call_function() 是某个 C 库的接口(动态链接到我的程序),是否可以将指针传递给某个模板函数的特定实例?指向(实例化)模板函数和常规函数的指针之间有什么区别吗?
我有一个关于std::move
在 C++ 中使用的问题。
假设我有以下类,它在其构造函数中采用 astd::vector
作为参数:
class A
{
public:
A(std::vector<char> v): v(v) {}
private:
std::vector<char> v;
};
Run Code Online (Sandbox Code Playgroud)
但如果我在某处写下以下内容:
std::vector<char> v;
A a(v);
Run Code Online (Sandbox Code Playgroud)
的复制构造函数std::vector
将被调用两次,对吧?那么我应该编写A
如下所示的构造函数吗?
class A
{
public:
A(std::vector<char> v): v(std::move(v)) {}
private:
std::vector<char> v;
};
Run Code Online (Sandbox Code Playgroud)
如果我想调用以下内容怎么办?
std::vector<char> v;
A a(std::move(v));
Run Code Online (Sandbox Code Playgroud)
构造函数的第二个版本可以吗?或者我应该为此创建另一个构造A
函数std::vector<char>&&
?
我想在C++中创建类似于锈不安全范围的东西.我的想法是我有一些功能执行检查次数.例如:
void check() {
if (...)
throw exception(...);
}
void foo() {
check();
// do some work
}
Run Code Online (Sandbox Code Playgroud)
现在,我希望能够在不执行这些检查的情况下使用或(在不同的上下文中)调用函数foo().理想情况下它看起来像这样:
foo(); // call foo and perform checks
unsafe {
foo(); // call foo without checks
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,是否有可能在编译时实现这样的东西?是否有可能以某种方式检查(或采取不同的行动)check
函数的调用范围?
我只提出了一个运行时解决方案:将它包装在一些lambda中:
unsafe([&] {
foo();
});
Run Code Online (Sandbox Code Playgroud)
不安全的地方如下:
void unsafe(std::function<void()> f)
{
thread_local_flag = unsafe;
f();
thread_local_flag = safe;
}
Run Code Online (Sandbox Code Playgroud)
check()函数只检查thread_local标志,并仅在设置为时执行检查safe
.
我有以下代码:
template <typename T>
struct wrapper {
T t;
operator T() { return t; }
T get() { return t; }
};
int main() {
int a[10];
int* x = a;
wrapper<long unsigned int> y{2};
std::cout << (x + y); // warning
}
Run Code Online (Sandbox Code Playgroud)
当我在 gcc 上编译它(在 7.3.0 和 8.2.0 上测试)时,-Wsign-conversion
我收到“警告:从‘long unsigned int’转换为‘long int’可能会改变结果的符号”。如果y
有 type long unsigned int
,则没有警告。此外,当我明确调用时y.get()
也没有警告:
std::cout << (x + y.get()); // this is ok
Run Code Online (Sandbox Code Playgroud)
为什么会出现这种情况呢?使用用户定义的转换时,是否有一些不能使用的指针算术特殊规则?
我想用自定义赋值运算符编写聚合模板结构,如下所示:
template <typename T>
struct Foo {
Foo() = default;
Foo(const Foo&) = default;
Foo& operator=(const Foo& f) { ... }
...
};
Run Code Online (Sandbox Code Playgroud)
现在,如果T
是我想要的const限定类型:
Foo& operator=(const Foo& f) = delete;
Run Code Online (Sandbox Code Playgroud)
我能想到的唯一方法是专门化Foo
struct:
template<T> struct Foo<const T> {
Foo& operator=(const Foo& f) = delete;
... a lot of code ...
}
Run Code Online (Sandbox Code Playgroud)
但是要专门化这个结构我必须复制粘贴所有剩余的代码(聚合意味着没有继承 - 至少在C++ 17之前,并且不可能将公共代码移动到基类).
有没有更好的方法呢?
我有一些模板类,其声明如下所示:
template <typename T, typename A, typename B, typename C>
class foo1;
template <typename T, typename A, typename B, typename C>
class foo2;
...
Run Code Online (Sandbox Code Playgroud)
我用它们在以下方面(每foo*
进行实例化A
,并B
和C
它bar
用实例化):
template <typename A, typename B, typename C>
class bar {
foo1<int, A, B, C> f1;
foo2<int, A, B, C> f2;
foo2<char, A, B, C> f3;
};
Run Code Online (Sandbox Code Playgroud)
为了简单和清晰的原因,我希望能够省略A
,B
并且C
内部的参数bar
只是写:
...
foo1<int> f1;
...
Run Code Online (Sandbox Code Playgroud)
我知道我可以为所有foo
类型使用别名模板,如下所示:
template <typename T> …
Run Code Online (Sandbox Code Playgroud) c++ templates template-meta-programming c++11 template-aliases
我有以下两个功能:
void bar(const std::string &s)
{
someCFunctionU(s.c_str());
}
void bar(const std::wstring &s)
{
someCFunctionW(s.c_str());
}
Run Code Online (Sandbox Code Playgroud)
这两个都调用一些C函数,分别接受const char *
或const wchar_t *
具有U
或具有W
后缀。我想创建一个模板函数来处理这两种情况。我尝试了以下尝试:
template <typename T>
void foo(const std::basic_string<T> &s)
{
if constexpr (std::is_same_v<T, char>)
someCFunctionU(s.c_str());
else
someCFunctionW(s.c_str());
}
Run Code Online (Sandbox Code Playgroud)
但这似乎无法正常工作。如果我打电话给:
foo("abc");
Run Code Online (Sandbox Code Playgroud)
这将无法编译。这是为什么?为什么编译器不能推断出正确的类型T
来char
?是否可以创建一个可以处理std :: string和std :: wstring的函数?