【问题标题】:Is it possible to define a typedef on a template class via a template method?是否可以通过模板方法在模板类上定义 typedef?
【发布时间】:2016-11-08 20:13:25
【问题描述】:

假设我有一个这样的模板类:

template <typename T>
struct TypeInformation {
    static int s_someArbitraryData;
}
template <typename T> TypeInformation<T>::s_someArbitraryData = 0;

然后,稍后我可以做这样的事情:

SomeFunction() {
    SetUpData<int>(); // Populates s_someArbitraryData for int.
}

仅通过调用 SetUpData,我就为给定类型设置了一份 s_someArbitraryData 副本。如果可能的话,我想做的是做类似的事情,但设置一种映射类型的方法。像这样的东西,目前不起作用:

template <typename T>
struct MyTypeMap {}

// ...

SomeFunction() {
    SetUpTypemap<int, float>(); // Creates a typedef on MyTypeMap<int>
    MyTypeMap<int>::type myFloatValue = 1.0f; // A float value
}

我可以通过这样的方式完成right now

template <>
struct MyTypeMap<int> {
    typedef float type;
}

但这对我的情况有一些烦人的缺点。我怀疑我想要的东西是不可能的,但如果有一些我不知道的深层模板魔法可以解决这个问题,我也不会感到惊讶。

【问题讨论】:

  • 您可以使用 C++11 或更高版本吗? using 语句可以给你一个模板化的 typedef。
  • 我不认为你能做到这一点(除了可修改的 constexpr 事情)
  • 你的第一个sn-p是不是错了? NameOfType 是什么?你的意思是TypeInformation
  • @AndyG:C++11 很好。我得调查一下。如果您可以比我自己弄清楚如何发布示例更快地发布示例,那么您可以获得声誉:)
  • @skypjack:是的,我的错。我在编写示例时更改了示例并且没有更新它。很好的收获。

标签: c++ templates typedef


【解决方案1】:

这可能与您正在寻找的东西相距不远:

#include<type_traits>

template<typename T>
struct tag { using type = T; };

template<typename...>
struct MapPart;

template<typename T, typename U, typename... O>
struct MapPart<T, U, O...>: MapPart<O...> {
    using MapPart<O...>::get;
    static constexpr tag<U> get(tag<T>) { return {}; }
};

template<>
struct MapPart<> {
    static constexpr void get();
};

template<typename... T>
struct Map: MapPart<T...> {
    template<typename U>
    using type = typename decltype(Map<T...>::template get<U>())::type;

    template<typename U>
    static constexpr auto get() {
        return MapPart<T...>::get(tag<U>{});
    }
};

int main() {
    using MyTypeMap = Map<int, float>;
    static_assert(std::is_same<MyTypeMap::type<int>, float>::value, "!");
    MyTypeMap::type<int> myFloatValue = 1.0f;
}

最终的语法略有不同。你有这个:

MyTypeMap::type<int>

而不是这个:

MyTypeMap<int>::type

反正我觉得可以接受。

MyTypeMap 类型仅在 using 声明的范围内可见。我认为这是原始SetUpTypemap&lt;int, float&gt; 函数的意图:仅在函数SomeFunction 内设置intfloat 之间的绑定。

通过使用这种方法,您可以同时建立多个关系。
举个例子:

using MyTypeMap = Map<int, float, float, int>;

// ....

MyTypeMap::type<int> myFloatValue = 1.0f;
MyTypeMap::type<float> myIntValue = 1;

另请注意,类型的第一个关系集是最强的。
换句话说,如果你这样做:

using MyTypeMap = Map<int, float, int, char>;

MyTypeMap::type&lt;int&gt; 类型将是float,它将隐藏intchar 之间的关系。

不是一个完美的解决方案,但也许可以解决您的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多