c++ - 模板推演失败

标签 c++ templates gcc variadic-templates sfinae

我正在尝试从 boost 库实现绑定(bind)功能。 下面您可以看到主结构体 bind_t 以及已定义的 operator()

我的问题如下:为什么我们应该在 decltype 中指定 operator() 的返回类型显式返回 call() 的类型作为成员函数(如果我删除call 之前的 this->,g++ 中模板参数推导失败。)

同样有趣的是,使用 clang++ 就没有这样的问题。

我不知道为什么会发生这种情况。

template <typename F, typename  ... P>
struct bind_t {
private:
    std::tuple<typename holder<P>::type...> p;
    F func;
    template <size_t ... N, typename ... Args>
    auto call(index_list<N ...>, Args const& ... args) const -> decltype(func(std::get<N>(p)(args...)...)) {
        return func(std::get<N>(p)(args...)...);
    }
public:
    bind_t(F f, P ... p):
        p(std::move(p)...),
        func(std::move(f))
    {}
    template <typename ... Args>
    auto operator()(Args const& ... args) const -> decltype(this->call(typename indices_by_num<sizeof...(P)>::type(), args...)) {
        typename indices_by_num<sizeof...(P)>::type indices;
        return call(indices, args...);
    }
};

full source实现情况
simple usecase

最佳答案

这是一个 gcc 错误,并记录在错误报告 decltype needs explicit 'this' pointer in member function declaration of template class with trailing return type 中其中说:

When using trailing return-type for member functions of a template class, the 'this' pointer must be explicitly mentioned. This should not be necessary (The implicit 'this' works with a non-template class).

Example:

template <typename T>
struct DecltypeConstThis {

    T f() const { return T{}; }

    auto g() -> decltype(this->f()) { return this->f(); }
    auto h() const  ->  decltype(f()) { return f(); } // this should work the same as g() above (with implicit 'this')

};

struct Working {
    int f() const { return 0; }
    auto h() const -> decltype(f()) { return 0; }
};


int main() {

    Working w;
    w.h();

    DecltypeConstThis<int> d;
    d.g();
    d.h();

    return 0;
}

该报告已标记为已修复,看起来该作品开始在 gcc 5.1 中工作( see it live )。

关于c++ - 模板推演失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34486443/

相关文章:

c++ - gcc 4.8 或更早版本是否存在关于正则表达式的问题?

c++ - 比较两个不同的枚举时,是否有避免警告的正确方法?

java - 原生比。 Protoc编译器选项

c++ - 如何使 QTextEdit 小部件从我的程序滚动

c++ - 与前向声明的类声明友元是否合法?

php - Opencart:从另一个 Controller 调用方法

c++ - 检查指向自定义类的指针是否不再存在

c++ - 模板参数推导和默认模板参数

javascript - 需要下划线模板帮助 - 模板化集合

c++ - 较新的 gcc 在头文件中给出非法语法错误