【发布时间】:2019-11-22 18:09:57
【问题描述】:
我正在尝试编写类似于std::bind 的东西,但用于模板类型而不是对象。实际上,我想将一个模板参数绑定到一个模板类型。 (以一种类似的方式,在std::bind 中,我们将一个(或多个)实参数绑定到一个函数对象。)
下面的 C++ 代码最好地说明了我想要什么:
#include <tuple>
#include <type_traits>
using namespace std;
/* This struct should be in some header-only utility library */
template <template <typename...> typename Template, typename T>
struct template_bind {
template <typename... Args>
using template_type = Template<T, Args...>;
};
/* This class should be in a separate header file */
// If we change the following line to add '...' then it works
// template <template <typename...> typename Template>
template <template <typename> typename Template>
class my_complicated_class {
public:
/* stuff */
private:
Template<float> data_;
};
/* This probably would be in a third file that includes both headers */
int main()
{
using t1 = template_bind<std::tuple, int>;
using t2 = template_bind<t1::template_type, double>;
my_complicated_class<t2::template_type> stuff_with_tuple; // Compile error
using p1 = template_bind<std::pair, int>;
my_complicated_class<p1::template_type> stuff_with_pair; // Compile error
}
有趣的是,代码可以在 GCC 和 MSVC 上使用 C++17 编译,但不能在 Clang(使用任何 C++ 标准)或 GCC/MSVC 上使用 C++14 编译。错误(在那些不会编译它的编译器上)是 my_complicated_class 需要一个模板模板参数,该参数接受 single 模板参数,但 template_type 是一个 variadic 模板。
将my_complicated_class 更改为接受可变参数模板模板参数可以解决所有编译器上的问题。但是,将my_complicated_class 更改为接受可变参数模板模板参数会感觉很奇怪,因为my_complicated_class 可能不应该知道所使用的模板模板参数的任何信息。 (否则,可以声明所有模板模板参数都应该写成可变参数模板,例如template <template <typename...> typename Template>,但这似乎不是模板模板参数通常的写法。)
哪些编译器不符合标准,如何使代码在 C++14 编译器上编译?
【问题讨论】:
标签: c++ templates c++14 variadic-templates template-templates