小编Igo*_*gor的帖子

C++标准是否允许双括号标量初始化?

我有以下代码:

int x = {{}};
Run Code Online (Sandbox Code Playgroud)

这种语法是否符合C++标准?(我对C++ 11及更高版本感兴趣.)

使用最新的编译器时没有问题,但是在一些较旧的编译器(例如GCC 4.8.5)中,它会出现以下错误:

错误:在'int'类型的标量初始值设定项周围括起来

c++ language-lawyer c++11

34
推荐指数
1
解决办法
1719
查看次数

是否允许将指向模板函数的指针传递给 C 库?(作为回调)

考虑以下代码:

#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 库的接口(动态链接到我的程序),是否可以将指针传递给某个模板函数的特定实例?指向(实例化)模板函数和常规函数的指针之间有什么区别吗?

c c++ templates metaprogramming

12
推荐指数
1
解决办法
409
查看次数

将 std::move 与向量一起使用

我有一个关于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++ move-semantics c++11

6
推荐指数
2
解决办法
1万
查看次数

是否有可能根据范围改变功能的行为?

我想在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.

c++ template-meta-programming c++11

6
推荐指数
1
解决办法
315
查看次数

为什么我会收到 Wsign 转换警告?

我有以下代码:

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)

为什么会出现这种情况呢?使用用户定义的转换时,是否有一些不能使用的指针算术特殊规则?

c++ gcc type-conversion implicit-conversion c++11

5
推荐指数
1
解决办法
2945
查看次数

如何在模板类中专门化赋值运算符?

我想用自定义赋值运算符编写聚合模板结构,如下所示:

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)

我能想到的唯一方法是专门化Foostruct:

template<T> struct Foo<const T> {
   Foo& operator=(const Foo& f) = delete;
   ... a lot of code ...
}
Run Code Online (Sandbox Code Playgroud)

但是要专门化这个结构我必须复制粘贴所有剩余的代码(聚合意味着没有继承 - 至少在C++ 17之前,并且不可能将公共代码移动到基类).

有没有更好的方法呢?

c++ templates template-specialization c++11 c++14

3
推荐指数
1
解决办法
227
查看次数

如何为模板类型创建别名?

我有一些模板类,其声明如下所示:

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,并BCbar用实例化):

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

3
推荐指数
1
解决办法
73
查看次数

使用模板处理字符串和字符串

我有以下两个功能:

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)

这将无法编译。这是为什么?为什么编译器不能推断出正确的类型Tchar?是否可以创建一个可以处理std :: string和std :: wstring的函数?

c++ templates template-meta-programming c++17

2
推荐指数
1
解决办法
380
查看次数