相关疑难解决方法(0)

是否可以编写模板来检查函数的存在?

是否可以编写一个模板来改变行为,具体取决于是否在类上定义了某个成员函数?

这是我想写的一个简单例子:

template<class T>
std::string optionalToString(T* obj)
{
    if (FUNCTION_EXISTS(T->toString))
        return obj->toString();
    else
        return "toString not defined";
}
Run Code Online (Sandbox Code Playgroud)

所以,如果class T已经toString()确定的话,就使用它; 否则,它没有.我不知道怎么做的神奇部分是"FUNCTION_EXISTS"部分.

c++ templates sfinae template-meta-programming

458
推荐指数
20
解决办法
14万
查看次数

如果类具有特定成员函数,则启用模板函数

我编写了以下模板函数,它检查仲裁容器是否包含特定元素:

template<template<class, class...> class container_t, class item_t, class... rest_t>
bool contains(const container_t<item_t, rest_t...> &_container, const item_t &_item) {
    for(const item_t &otherItem : _container) {
        if(otherItem == _item) { return true; }
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

这适用于大多数容器.然而,对于所有类型的集合(和地图),它是次优的,因为我们可以使用:

template<template<class, class...> class set_t, class item_t, class... rest_t>
bool contains(const set_t<item_t, rest_t...> &_set, const item_t &_item) {
    return _set.count(_item) > 0;
}
Run Code Online (Sandbox Code Playgroud)

显然,由于含糊不清,我们不能同时使用这两个模板.现在我正在寻找一种方法,用于std::enable_if启用第一个模板,如果container_t不提供count成员函数,第二个模板,如果它没有.但是我无法弄清楚如何检查特定成员函数(使用C++ 11).

c++ templates sfinae c++11

11
推荐指数
1
解决办法
879
查看次数

尝试访问类的私有成员以防止超载是不正确的?

在尝试创建特征以检查类字段是否公开可用时,我创建了一个代码:

#include <type_traits>
#include <utility>

template <class T, class = void>
struct does_not_have_foo: std::true_type {};

template <class T>
struct does_not_have_foo<T, decltype(std::declval<T>().foo, void())>: std::false_type {};

class Foo {
    int foo;
};

int main() {
    static_assert(does_not_have_foo<Foo>::value);
}
Run Code Online (Sandbox Code Playgroud)

但它似乎未能在[gcc]中编译([clang]似乎在这里更宽松)并出现错误:

prog.cc:8:56: error: 'int Foo::foo' is private within this context
Run Code Online (Sandbox Code Playgroud)

我为我的一些旧代码挖出了类似的东西,归结为以下内容:

template <class T>
auto does_not_have_foo(T t) -> decltype(t.foo, std::false_type()) {
    return {};
}

std::true_type does_not_have_foo(...) { return {}; }

class Foo {
    int foo;
};

int main() {
    static_assert(decltype(does_not_have_foo(Foo{}))::value);
} …
Run Code Online (Sandbox Code Playgroud)

c++ private-members sfinae type-traits language-lawyer

7
推荐指数
1
解决办法
149
查看次数

当我们声明与基类成员变量同名的变量时,为什么编译器会生成有关遮蔽的警告?

当我添加 -Wshadow 标志时,编译器(gcc 12.1.0)会为以下代码生成以下警告:

prog.cc: In member function 'void Derived::myfunc()':
prog.cc:16:13: warning: declaration of 'i' shadows a member of 'Derived' [-Wshadow]
   16 |         int i = 3;
      |             ^
prog.cc:8:9: note: shadowed declaration is here
    8 |     int i{2};
      |       
Run Code Online (Sandbox Code Playgroud)
class Base
{
private:
    int i{2};
};

class Derived : public Base
{
public:
    void myfunc(void)
    {
        int i = 3;
        std::cout << i << "\n";
    }
};
Run Code Online (Sandbox Code Playgroud)

我的想法是:因为我们不能在 myfunc 中仅使用“i”变量(因为它是编译时错误),所以没有必要发出这样的警告。

您知道为什么编译器在这种情况下会发出警告吗?

c++

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