- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如果使用程序为某个模板参数调用非类型模板类方法,我想生成一个编译器错误。
typedef SubWithTemplate<1> SubWithTemplate1;
typedef SubWithTemplate<2> SubWithTemplate2;
SubWithTemplate1 &subWithTemplate1 = SubWithTemplate1::instance;
SubWithTemplate2 &subWithTemplate2 = SubWithTemplate2::instance;
subWithTemplate1.doSomething(); // Should compile OK
subWithTemplate1.doSomethingElse(); // Should compile OK
subWithTemplate2.doSomething(); // Should NOT compile OK
subWithTemplate2.doSomethingElse(); // Should compile OK
我的起点是以下两个类:
super .h:
class Super {
protected:
Super() {}
public:
virtual void doSomething();
void doSomethingElse();
};
super .cpp:
void Super::doSomething() {}
void Super::doSomethingElse() {}
SubWithTemplate.h:
template<int SUBNUMBER>
class SubWithTemplate : public Super {
public:
static SubWithTemplate<SUBNUMBER> instance;
void doSomething() {
// Do something
};
private:
SubWithTemplate() : Super() {}
};
template<int SUBNUMBER>
SubWithTemplate<SUBNUMBER> SubWithTemplate<SUBNUMBER>::instance;
我对 Boost 或 mpl 不是很流利,但我有一些模糊的感觉 BOOST_MPL_ASSERT 可以给我带来一些成功。但我无法理解其中的本质。
我试过类似的方法:
SubWithTemplate.h:
...
void doSomething() {
BOOST_MPL_ASSERT_MSG(<some test on SUBNUMBER being different from 2 and 7 and less than 25>, <what here?>, <what here?> )
};
...
我不希望 Super 被模板化,因为它应该是所有子类的相同实例。
如果我可以避免在 doSomething 上使用 virtual,那就更好了。
如果有比我更专业的人能帮助我,我将不胜感激。
最佳答案
这不是一个很好的解决方案,但是...如果您可以使用 C++11,禁用 doSomething()
怎么样?通过 SFINAE?
在以下示例中 doSomething()
为 SUBNUMBER
的所有值启用除了 2
#include <type_traits>
class Super
{
protected:
Super () {}
void doSomething () {}
public:
void doSomethingElse () {}
};
template <int SUBNUMBER>
class SubWithTemplate : public Super
{
public:
static SubWithTemplate<SUBNUMBER> instance;
template <int I = SUBNUMBER>
typename std::enable_if<I!=2>::type doSomething ()
{ Super::doSomething(); }
private:
SubWithTemplate () : Super() {}
};
template<int SUBNUMBER>
SubWithTemplate<SUBNUMBER> SubWithTemplate<SUBNUMBER>::instance;
typedef SubWithTemplate<1> SubWithTemplate1;
typedef SubWithTemplate<2> SubWithTemplate2;
int main()
{
SubWithTemplate1 &subWithTemplate1 = SubWithTemplate1::instance;
SubWithTemplate2 &subWithTemplate2 = SubWithTemplate2::instance;
subWithTemplate1.doSomething(); // OK
subWithTemplate1.doSomethingElse(); // OK
//subWithTemplate2.doSomething(); // compilation error
subWithTemplate2.doSomethingElse(); // OK
}
--- 编辑 ---
正如 Guillaume Racicot 所指出的(谢谢!)这个解决方案可以通过显式模板值来规避(I = SUBNUMBER
只是一个默认值)。
如果
subWithTemplate2.doSomething();
给出一个编译错误(按照 OP 的要求),
subWithTemplate2.doSomething<1>();
编译没有问题。
为了避免这种情况,我可以提出几个解决方案。
(1) 你可以添加一个static_assert()
, 在函数体中,强加 I == SUBNUMBER
;像
template <int I = SUBNUMBER>
typename std::enable_if<I!=2>::type doSomething ()
{
static_assert(I == SUBNUMBER, "I != SUBNUMBER; this in wrong");
Super::doSomething();
}
(2) 按照 Guillaume Racicot 的建议(再次感谢!),您可以整合 I == SUBNUMBER
在std::enable_if<>
测试;像
template <int I = SUBNUMBER>
typename std::enable_if<(I!=2) && (I == SUBNUMBER)>::type
doSomething ()
{ Super::doSomething(); }
我发现第二种解决方案更优雅一些,但我不是专家,对我来说,这是一个品味问题。
--- 编辑 2 ---
how could I prevent the SubWithTemplate class from being instantiated unless the SUBNUMBER is within a given interval?
防止全类火爆?不仅是 doSomething()
方法?
我想到的第一个方法是使用 static_alert()
.
例如,如果您只想获得许可 SUBNUMBER
s在[5,10[(含5,不含10)范围内,可以按如下方式编写构造函数。
SubWithTemplate () : Super()
{ static_assert((SUBNUMBER >= 5) && (SUBNUMBER < 10), "error message"); }
但我想还有其他方法。
--- 编辑 3 ---
另一种防止 SubWithTemplate 类被实例化的方法,除非 SUBNUMBER 在给定的时间间隔内。
一种在 C++98 中也适用的方法。
它基于默认特化和模板默认值。
class Super
{
protected:
Super () {}
void doSomething () {}
public:
void doSomethingElse () {}
};
template<bool b> struct boolWrapper {};
template <int I, bool = (I >= 0) && (I <= 20)>
struct rangeLimit;
template <int I>
struct rangeLimit<I, true>
{ };
template <int SUBNUMBER>
class SubWithTemplate : public Super, public rangeLimit<SUBNUMBER>
{
public:
static SubWithTemplate<SUBNUMBER> instance;
void doSomething ()
{ Super::doSomething(); }
private:
SubWithTemplate () : Super() {}
};
template<int SUBNUMBER>
SubWithTemplate<SUBNUMBER> SubWithTemplate<SUBNUMBER>::instance;
typedef SubWithTemplate<1> SubWithTemplate1;
typedef SubWithTemplate<2> SubWithTemplate2;
typedef SubWithTemplate<20> SubWithTemplate20;
//typedef SubWithTemplate<21> SubWithTemplate21; compilation error
int main()
{
}
关于c++ - 如何在尝试为某些非类型值实例化模板子类方法时产生编译器错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41539005/
有没有一种方法可以使用标准类型构造函数(例如 int、set、dict、list、tuple 等)以用户定义的方式将用户定义类的实例强制转换为其中一种类型?例如 class Example:
我知道这个问题在Stackoverflow中有很多问题,但是即使有很多答案,这些答案也帮不了我什么,也没有找到答案。 在我的WebAPP中,它可以正常工作,但是当我将其转换为API时,它失败了(主题标
这个问题已经有答案了: Why does the ternary operator unexpectedly cast integers? (3 个回答) 已关闭 9 年前。 最近遇到一个Java的陷
我尝试使用 FirebaseApp.configure() 配置 Firebase,但遇到以下崩溃: *** Terminating app due to uncaught exception 'c
我有一个自连接员工实体类,其中包含与其自身相关的 id、name 和 ref 列。我想创建它的新实例并将其保存到数据库。 首先我创建了一个 Employee 类的实例并将其命名为 manager。然后
我有一个用于添加新公寓的表单,在该表单中我有一个下拉列表,用户可以在其中选择负责的人员。 显然,当您从下拉列表中选择并尝试保存公寓时,我的应用程序认为该人已被修改。它给了我下面的错误,指示我应该首先保
从 Visualforce 页面,我需要检索我们组织的 salesforce 实例的 URL,而不是 Visual Force URL。 例如我需要https://cs1.salesforce.com
我遇到了一些可能的问题答案,但这是关于从 Hibernate 3.4.0GA 升级到 Hibernate 4.1.8 的问题。所以这曾经在以前的版本下工作,我已经四处搜索了为什么它在这个新版本中出现了
似乎一遍又一遍地问这个问题,我仍然找不到解决我问题的答案。我在下面有一个域模型。每个新创建或更新的“安全用户”都需要我确保其具有配置文件,如果没有,则创建一个新的配置文件并分配给它。 配置文件的要求相
我很难调试为什么 JPA 不级联我的 @ManyToMany 关系。我发现的所有答案都与缺少级联语句有关。但我确实拥有它们并且仍然得到: Caused by: org.hibernate.Transi
Play 服务 API 表明有一个叫做 Instance ID 的东西 但是,在 Android Studio 中包含以下内容后,我无法导入 InstanceID 类 compile "com.goo
我正在使用 Seam 框架。我有 2 个实体: 请求.java @Entity @Table(name = "SRV_REQUEST") public class Request { private
This question处理构建一个适当的Monad来自单子(monad)的实例,但仅在某些约束下 - 例如Set .诀窍是将其包装成 ContT ,它将约束推迟到包装/展开其值。 现在我想对 Ap
我正在尝试执行此查询: StringBuffer sb = new StringBuffer(); sb.append("select p from PointsEntity p " + "where
我试图了解是否可以更改我的 hibernate 配置并使用单个 MySQL 实例(而不是我当前拥有的多个 MySQL 实例): 我有一个使用 hibernate 的 Java 应用程序,与 2 个模式
我有一个选项卡滑动布局,其中包括四个选项卡,每个选项卡都有自己的布局和 fragment ,在我的主要 Activity 布局中,viewpager 参与更改选项卡。特定 View (选项卡)在应用程
我看到很多帖子声称他们正在运行 MySql 的 RDS 实例,但无法连接到该实例,但我没有运行 RDS。 我使用 EC2 实例来托管我的 WordPress 博客,该博客是使用 Web 平台安装程序安
因为我在我的 ec-2 实例上的 python 虚拟环境中运行应用程序( Airflow ),并且我想在同一个 ec2 实例上的默认 python 环境中运行命令,所以我认为 ssh 到我自己的实例更
这个问题已经有答案了: How to fix the Hibernate "object references an unsaved transient instance - save the tra
例子: run APP1 .. ... run APP1 ... run APP2 如何在 APP2 中对 Vue 说我需要调用 APP1?
我是一名优秀的程序员,十分优秀!