如何通过非类型参数

时间:2017-10-03 21:19:00

标签: c++ c++11

我想定义一个带有非类型参数的可变参数模板类,并使用嵌套模板类,我可以通过其中一个可变参数模板参数获得专门化。

我的问题类似于C++ variadic template with non-type parameters of different types。但我想为嵌套类专门化一个所有者类的参数

struct Data
{
    std::string field1;
    std::string field2;
    bool field3 = false;
    int field4 = 0;
};

template <typename ... Types>
struct Wrapper
{
    template <Types ... Args>
    struct Holder
    {
    };
};

它有效:

using W = Wrapper<decltype(&Data::field1), decltype(&Data::field2), decltype(&Data::field3), decltype(&Data::field4)>;
    using H = W::Holder<&Data::field1, nullptr, nullptr, nullptr>;

但我需要将其用作

using H = W::Holder<&Data::field3>;

我该如何实现?

类似的代码

#include <iostream>
#include <string>
#include <type_traits>

struct Data
{
    std::string field1;
    std::string field2;
    bool field3 = false;
    int field4 = 0;
};

struct Null;

template <typename T, T>
struct Holder
{
};

template <typename H, typename ... T>
struct Select
    : Select <T ... >
{
    using Base = Select <T ... >;
    using Base::Get;

    template <H F>
    static Holder<H, F> Get();
};

template <>
struct Select<Null>
{
    static void Get();
};

int main()
{
    using S = Select<std::string Data::*, bool Data::*, int Data::*, Null>;
    using H = decltype(S::Get<&Data::field3>());
    static_assert(std::is_same<H, Holder<decltype(&Data::field3), &Data::field3>>::value, "Problem ...");
    return 0;
};

但我需要在没有decltype和函数

的情况下这样做

正确的解决方案是

using H = W::Holder<&Data::field3>;

2 个答案:

答案 0 :(得分:0)

由于您没有指定标准修订版,我假设您没有偏好设置。好吧,在C ++ 17中你可以这样做:

template<typename Type>
struct Base {
    template <Type>
    struct Holder {};
};

template <typename ... Types>
struct Wrapper: Base<Types>... {
    template<auto Arg>
    using Holder = typename Base<decltype(Arg)>::template Holder<Arg>;
};

至少只要它符合您的评论:

  

所有类型都是唯一的:using W = Wrapper<std::string Data::*, bool Data::*, int Data::*>;

以下内容符合预期:

using W = Wrapper<decltype(&Data::field1), decltype(&Data::field3), decltype(&Data::field4)>;
using H = W::Holder<&Data::field3>;

wandbox上查看。

答案 1 :(得分:0)

中,传递给模板的非类型值必须具有固定类型。此类型可能取决于先前的类型参数,但必须由它们修复。

您希望将非类型参数作为第一个参数传递,并为其指定变量类型。

没有&#34;模板重载决议&#34;可用的选项。

还有其他技巧,例如调度到宏或其他任何标签,也可以解决您的问题。但是你已经指定了你想要的语法。

您的问题过于严格,无法按照规定解决。

所以你运气不好。升级编译器的版本,稍后再试,或者在下一个问题中删除不必要的约束。