首页 > 解决方案 > 模板模板参数替换失败

问题描述

我想要一个辅助函数来为我实例化一个类。目前它无法在 clang 中编译(尽管它在 gcc 中编译工作),但我也需要它在 clang 中工作。目前我正在使用clang version 6.0.0-1ubuntu2.

我不确定它为什么会失败,因为 gcc 能够检测到类型。我尝试从这篇文章中做一些事情并玩了一段时间,但我一直在撞墙。MCVE 可用,或者您可以在coliru上试用:

#include <vector>

using namespace std;

template <typename T, template <typename> typename Container>
struct SomeClass {
    SomeClass(const Container<T>& c) {
    }
};

template <typename T, template <typename> typename C>
inline auto make_some_class(const C<T>& container) {
    return SomeClass<T, C>(container);
}

int main() {
    vector<int> ints;

    auto stuff = make_some_class(ints);  
}

main.cpp:19:18: 错误: 没有匹配函数调用'make_some_class'

   auto stuff = make_some_class(ints);  

                ^~~~~~~~~~~~~~~

main.cpp:12:13:注意:候选模板被忽略:替换失败 [with T = int]:模板模板参数的模板参数与其对应的模板模板参数不同

inline auto make_some_class(const C<T>& container) {

            ^

产生 1 个错误。

标签: c++templatesc++17variadic-templatestemplate-argument-deduction

解决方案


建议:试试

#include <vector>

template <template <typename...> typename Container, typename ... Ts>
struct SomeClass {
    SomeClass(const Container<Ts...>& c) {
    }
};

template <template <typename...> typename C, typename ... Ts>
inline auto make_some_class(const C<Ts...>& container) {
    return SomeClass<C, Ts...>(container);
}

int main() {
    std::vector<int> ints;

    auto stuff = make_some_class(ints);  
}

我的意思是......我想问题是std::vector不是接收一种类型模板参数的容器;它是一个接收两种类型模板参数的容器(第二个具有默认类型:第一个std::allocator<T>在哪里T)。

所以建议是:让SomeClass容器更加灵活,能够接收带有参数模板类型的可变参数列表的容器

template <typename...> typename Container

以及相应的模板类型列表

typename ... Ts

如果你想要一个可变参数列表 ( Ts...) 你需要它在最后一个位置所以你必须切换ContainerT(now ) 的位置: 在可变参数列表Ts...之前和之后ContainerTs...

template <template <typename...> typename Container, typename ... Ts>
struct SomeClass {
    SomeClass(const Container<Ts...>& c) {
    }
};

不是严格要求,但为了统一起见,我建议以相同的方式重写make_some_class()(显然,在模板参数列表中传递C之前)。Ts...

template <template <typename...> typename C, typename ... Ts>
inline auto make_some_class(const C<Ts...>& container) {
    return SomeClass<C, Ts...>(container);
}

推荐阅读