c++ - 为什么 Clang++ 编译器无法编译以下可变参数模板代码?

标签 c++ c++14 clang++

#include <string>
#include <iostream>
#include <tuple>
#include <utility>


template<typename... T> struct test {

    using args_type = std::tuple<T...>;

    args_type x;

    template<std::size_t... I>
    void callme(std::index_sequence<I...>) {
        int _[] = {(std::get<I>(x).std::tuple_element<I, args_type>::type::~type(), true)...};
    }
};

int main() {
}

错误信息是

clang-3.7  -std=gnu++1y  -Wc++14-extensions test.cpp
test.cpp:15:56: error: expected ')'
        int _[] = {(std::get<I>(x).std::tuple_element<I, args_type>::type::~type(), true)...};
                                                       ^
test.cpp:15:20: note: to match this '('
        int _[] = {(std::get<I>(x).std::tuple_element<I, args_type>::type::~type(), true)...};
                   ^
1 error generated.

同样的代码似乎可以用 G++ 4.9.2 编译得很好。我还找不到关于 Clang 的任何相关错误报告。

最佳答案

似乎是一个 Clang 错误,尽管此类伪析构函数名称的查找可能存在缺陷并且是开放 CWG 问题的主题,特别是 555 和 399。

扩展模式的重要部分是

std::get<I>(x).std::tuple_element<I, args_type>::type::~type()

在这里,. 之间的位和 ()是一个伪析构函数名;合格的名称查找然后要求

If a pseudo-destructor-name (5.2.4) contains a nested-name-specifier, the type-names are looked up as types in the scope designated by the nested-name-specifier. Similarly, in a qualified-id of the form:

        nested-name-specifieropt  class-name :: ~ class-name

the second class-name is looked up in the same scope as the first.

typestd::tuple_element<I, args_type> 中查找,它被发现指的是某种类型。请注意,class-name 是标识符(和 simple-template-id)的语法名称,不需要引用实际的类。 std::get<I>(x).std::tuple_element<I, args_type>::type::~type then 引用 type 的析构函数.

使用辅助函数的解决方法:

template <typename T>
void destroy(T& p) {p.~T();}

template<typename... T> struct test {
    using args_type = std::tuple<T...>;

    args_type x;

    template<std::size_t... I>
    void callme(std::index_sequence<I...>) {
        int _[] = {(destroy(std::get<I>(x)), 0)...};
    }
};

关于c++ - 为什么 Clang++ 编译器无法编译以下可变参数模板代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30201414/

相关文章:

c++ - move 构造函数(错误 : call to implicitly-deleted copy constructor)

c++ - 无法链接 GLEW 库

c++ - 将 qt creator 项目移植到 windows 时出现 z.lib 问题

c++ - 为什么来自对齐的 std::array 的初始自动矢量化加载是标量? (g++/叮当++)

c++ - 我如何让这个递归规则起作用?

c++ - 为什么 C++ 允许您使用已删除的 move 操作来 move 包含对象的类?

c++ - 同名的嵌套类和成员函数

c++ - For循环中的多个计数器问题

c++ - Visual Studio 10中使用/MT或/MD构建dll

c++ - 如何存储多态闭包?