我正在尝试编写类似于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
需要一个模板模板参数,该参数接受单个模板参数,但它template_type
是一个可变参数模板。
更改my_complicated_class
为接受可变参数模板模板参数可修复所有编译器上的问题。但是,更改my_complicated_class
为接受可变参数模板模板参数会感觉很奇怪,因为my_complicated_class
可能不应该知道有关使用的模板模板参数的任何信息。(否则,可以提出一个论点,即所有模板模板参数都应编写为可变参数模板,例如template <template <typename...> typename Template>
,但这似乎不是通常编写模板模板参数的方式。)
哪些编译器不符合标准,如何在 C++14 编译器上编译代码?
Clang 不支持 C++17 模板模板参数/参数匹配。
相关段落:
当模板参数的相应类模板或别名模板(称为 A)的模板参数列表中的每个模板参数与中的相应模板参数匹配时,模板参数匹配模板模板参数(称为 P) P 的模板参数列表。 [...]
当 P 至少与模板参数 A 一样专业时,模板参数与模板模板参数 P 匹配。 [...]
这是使您的代码在 C++17 中格式良好的最后一句话。当 P istemplate<class> class
且 A is 时template<class...> class
,P 比 A 更专业。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句