【问题标题】:Skipping explicit template initialization to avoid double initialization [closed]跳过显式模板初始化以避免双重初始化
【发布时间】:2016-07-22 22:41:43
【问题描述】:

我尝试制作一个仅适用于双精度类型和用户定义类型的模板。 用户可以通过包含的头文件中的 typedef 来选择用户定义的类型。

typedef float Usertype;

我通过在模板源文件末尾写下以下内容解决了这个问题:

template class SpaceDiscretizer<Datatype::Usertype>;
template class SpaceDiscretizer<double>;

但是,当用户将 Usertype 定义为 double 时,我遇到了问题! 我试图遵循一些方向,即这些主题:How can I provide template specializations for typedefs of the same type?,Conditional explicit template instantiation

struct dummy{};
template class SpaceDiscretizer< std::conditional<std::is_same<double,Datatype::Usertype>::value, dummy, double>::type>;
//typedef typename std::enable_if<false,double>::type mytype;
//template class SpaceDiscretizer<mytype>;
template class SpaceDiscretizer<Datatype::Usertype>;

第一个不起作用,因为如果 SpaceDiscretizer 用任何不复杂的东西初始化,除了双精度,它不起作用。但我想为用户提供一种简单的方法来添加一个可行的替代方法来替代该功能。 第二次(已注释掉)尝试失败,因为这不是重载,如果 type 不存在,mytype 将不会被忽略,而是会输出错误。

编辑: 我有很多地方不使用模板,或者必须确保多个未连接的类使用相同的数据类型。我需要将实现保留在 .cpp 文件中。为了解决这个问题,我在所有相关位置都包含了一个头文件,以便用户可以在一个位置更改值并使其保持一致。问题来了,因为我一直想为double初始化,但是用户指定double作为Usertype是很自然的。

【问题讨论】:

  • 这个设计让我觉得有点不寻常。是什么阻止某人做using UserType = int 之类的事情,然后明确写SpaceDiscretizer&lt;int&gt;?这不是你想要允许的,但在这种情况下它是完全合法的。我怀疑您可能试图以错误的方式做某事。
  • 问题中没有足够的信息。但是似乎 SpaceDiscretizer 依赖于 Datatype::Usertype 的某些成员,该成员不存在于 double 中。
  • @templatetypedef 我的想法是,我认为头文件属于我自己或受过教育的开发人员领域,并且纯粹使用 SpaceDiscretizer 作为可避免的“最终用户”错误。

标签: c++ templates c++11


【解决方案1】:

我不确定你想要什么,但是……希望下面的例子能有所帮助

#include <iostream>
#include <type_traits>

typedef  float  userT;
//typedef  double  userT;

template <typename T, bool B = std::is_same<T, double>::value>
class SpaceDiscretizer;

template <>
class SpaceDiscretizer<userT, false>
 { public: static constexpr int val = 1; };

template <>
class SpaceDiscretizer<double>
 { public: static constexpr int val = 2; };

int main ()
 {
   SpaceDiscretizer<userT>   sd1;
   SpaceDiscretizer<double>  sd2;

   std::cout << "sd1 val = " << sd1.val << std::endl;
   std::cout << "sd2 val = " << sd2.val << std::endl;

   return 0;
 }

输出是

sd1 val = 1
sd2 val = 2

当userT被定义为float和

sd1 val = 2
sd2 val = 2

当userT 定义为double。

ps:对不起,我的英语不好。

【讨论】:

  • 感谢您的评论,我只想跳过显式初始化。据我了解您的解决方案,我必须使用完全相同的实习生代码对课程进行两次专业化。我无法仅使用 template class SpaceDiscretizer; 做同样的事情
  • @AYWer - 抱歉,我不明白你到底需要什么(我的英语可能有问题)。您到底想跳过什么“显式初始化”?而且我不明白“确切的实习生代码”是什么意思。考虑到我的只是一个例子,但你可以在很多不同的模式下修改它。
猜你喜欢
  • 2018-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-21
  • 2021-10-27
相关资源
最近更新 更多