避免模​​板参数列表中的自动

时间:2017-11-18 10:26:58

标签: c++ templates

假设我有一个像这样的课程模板

template <auto Arg> class X;

但由于我使用的是MSVC 2017.5,因此不支持模板参数列表中的auto,我必须写

template <typename T, T Arg> class X;

并通过X<int, 5>明确地命名该类型,而不是使用自动扣除。现在,有没有办法在模板参数列表中没有auto的情况下获得相同的结果?

具体来说,我有以下问题。

template <typename C, typename T>
using Func = const T& (C::*)(void) const;

template <typename C, typename T, Func<C, T> F>
class X;

我可以像这样使用X

class Y { const int &getInt() const; }

X<Y, int, &Y::getInt> x;

当然,如果可能,我希望避免明确命名Yint

1 个答案:

答案 0 :(得分:4)

你只有一个前C ++ 17的追索权,它不漂亮或推荐。您必须转向预处理器。只有这样才能“自动提取类型”。

#include <iostream>

template <typename C, typename T>
using Func = const T& (C::*)(void) const;

template<typename PMem, PMem f> class X;

template <typename C, typename T, Func<C, T> F>
class X<Func<C, T>, F> {};

#define MAKE_X(...) X<decltype(__VA_ARGS__), __VA_ARGS__>

struct Y { const int &getInt() const; };


int main() {
    MAKE_X(&Y::getInt) x;
    return 0;
} 

关键部分是MAKE_X。它将发出与你给它相同的标记,作为decltype的参数并且不变。这是一个自动提取表达式类型的黑客。

毋庸置疑,它并不像适当的auto参数那么好。