【发布时间】:2014-03-28 19:08:29
【问题描述】:
这个问题与this one 相关,只是我尝试使用枚举非类型模板参数,而不是处理类型名模板参数。
在非类型模板参数的情况下,是否可以有一个模板化(类成员函数)只有特化,没有通用(工作)定义?
通过在类主体中声明并仅提供特化,我能够使一个版本正常工作,但任何使用未定义模板参数的滥用调用在链接之前都不会产生错误。更糟糕的是,缺少的符号暗指枚举的整数值,而不是它的名称,所以它会让其他开发人员感到困惑。
我能够从引用的问题中获得
BOOST_STATIC_ASSERT技术,使其仅适用于 typename 模板参数。
这段代码演示了这个想法。我不想编译 CAT-version 调用:
#include <iostream>
#include <boost/static_assert.hpp>
// CLASS HEADER FILE:
struct foo_class
{
enum AllowedTypes { DOG, CAT };
template <AllowedTypes type>
void add_one_third( double bar ) const
{
BOOST_STATIC_ASSERT_MSG(sizeof(type)==0, "enum type not supported.");
}
};
// CLASS SOURCE FILE
template<>
void foo_class::add_one_third<foo_class::DOG>( double bar ) const
{
std::cout << "DOG specialization: " << bar + 1./3. << std::endl;
}
// USER SOURCE FILE
int main()
{
std::cout << "Template Specialization!\n\n";
foo_class a;
a.add_one_third<foo_class::DOG>(3.0); // should succeed
// Compilation fails with or without the following line:
a.add_one_third<foo_class::CAT>(3.0); // should fail at compile-time
return 0;
}
背景: 我有一个类成员函数,它接受一个枚举“ArgType”和一个名称。
void declareKernelArgument( ArgType type, std::string name );
定义已变成if..else..if..else 列表,用于六种左右允许的 ArgType 案例。我还必须有最后一个案例,它会为不允许的 ArgType 抛出异常。我认为将 ArgType 移动到模板参数并为每个允许的 ArgType 提供专业化会更干净。误用会在编译时被发现。
【问题讨论】:
-
为什么你更喜欢枚举标记而不是类型本身,或者基于类型的标记?
-
我选择的
T_INT和T_DOUBLE是我现在意识到的糟糕的坏名字。我会将其更改为与真实类型不太混淆的东西,因为这是我的实际使用兴趣。 -
这个想法是能够注释掉 add_one_third 的第二次调用并且编译应该成功。它没有。
标签: c++ enums template-specialization static-assert