Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否可以在模板类中有方法和变量的条件声明?_C++_Templates - Fatal编程技术网

C++ 是否可以在模板类中有方法和变量的条件声明?

C++ 是否可以在模板类中有方法和变量的条件声明?,c++,templates,C++,Templates,我试图创建一个类,该类可以具有由模板参数控制的函数和成员。我在想这样的事情 template<int control> class ControlledDeclaration { public: if(1 == control) int Get() { return 0; } else if(2 == control) char* Get() { return "get"; } else if (3 == control)

我试图创建一个类,该类可以具有由模板参数控制的函数和成员。我在想这样的事情

template<int control>
class ControlledDeclaration
{
public:
    if(1 == control)
        int Get() { return 0; }
    else if(2 == control)
        char* Get() { return "get"; }
    else if (3 == control)
        bool Get() { return true; }
};

void test_template()
{
    ControlledDeclaration<1> c_int;
    ControlledDeclaration<2> tx_int;
    ControlledDeclaration<3> b_int;
}
模板
类受控退化
{
公众:
if(1==控制)
int Get(){return 0;}
else if(2==控制)
char*Get(){返回“Get”;}
else if(3==控制)
bool Get(){return true;}
};
无效测试模板()
{
受控衰减系数;
受控衰减传输;
控制性减损;
}

如果可能,怎么做?

看一看,这正是你想要的。

看一看,这正是你想要的。

我将使用的方法是专门化traits类中的细节,并使用模板提供接口。在这个简单的例子中,使用traits而不是专门化实际类型并没有多大好处,但是一般来说,使用traits比专门化更容易定制几个变化点

template <int> struct ControlDeclarationTraits;
template <>
struct ControlDeclarationTraits<1> {
    typedef int type;
    static int value() { return 0; };
};

template <>
struct ControlDeclarationTraits<2> {
    typedef char const* type;
    static char const* value() { return "get"; }
};

template <>
struct ControlDeclarationTraits<3> {
    typedef bool type;
    static bool value() { return true; }
};

template<int control>
class ControlledDeclaration
{
public:
    typename ControlDeclarationTraits<control>::type Get() {
        return ControlDeclarationTraits<control>::value();
    }
};
模板结构ControlDeclarationTraits;
模板
结构ControlDeclarationTraits{
typedef int类型;
静态int值(){return 0;};
};
模板
结构ControlDeclarationTraits{
typedef char const*类型;
静态字符常量*值(){return“get”;}
};
模板
结构ControlDeclarationTraits{
类型定义布尔类型;
静态布尔值(){return true;}
};
模板
类受控退化
{
公众:
typename ControlDeclarationTraits::type Get(){
返回ControlDeclarationTraits::value();
}
};

顺便说一句,字符串文字的类型是
char const[n]
(对于合适的
n
)而不是
char[n]
,即,您不能真正使用字符串文字来初始化
char*
。它确实有效,因为它被认为有必要支持现有代码将字符串文本分配给
char*
,但实际上这是一个谎言:尝试将值分配给任何值都会导致未定义的行为。设置指针
const
可以明显看出内容不需要修改。

我将使用的方法是在traits类中专门化细节,并使用模板提供接口。在这个简单的例子中,使用traits而不是专门化实际类型并没有多大好处,但是一般来说,使用traits比专门化更容易定制几个变化点

template <int> struct ControlDeclarationTraits;
template <>
struct ControlDeclarationTraits<1> {
    typedef int type;
    static int value() { return 0; };
};

template <>
struct ControlDeclarationTraits<2> {
    typedef char const* type;
    static char const* value() { return "get"; }
};

template <>
struct ControlDeclarationTraits<3> {
    typedef bool type;
    static bool value() { return true; }
};

template<int control>
class ControlledDeclaration
{
public:
    typename ControlDeclarationTraits<control>::type Get() {
        return ControlDeclarationTraits<control>::value();
    }
};
模板结构ControlDeclarationTraits;
模板
结构ControlDeclarationTraits{
typedef int类型;
静态int值(){return 0;};
};
模板
结构ControlDeclarationTraits{
typedef char const*类型;
静态字符常量*值(){return“get”;}
};
模板
结构ControlDeclarationTraits{
类型定义布尔类型;
静态布尔值(){return true;}
};
模板
类受控退化
{
公众:
typename ControlDeclarationTraits::type Get(){
返回ControlDeclarationTraits::value();
}
};

顺便说一句,字符串文字的类型是
char const[n]
(对于合适的
n
)而不是
char[n]
,即,您不能真正使用字符串文字来初始化
char*
。它确实有效,因为它被认为有必要支持现有代码将字符串文本分配给
char*
,但实际上这是一个谎言:尝试将值分配给任何值都会导致未定义的行为。设置指针
const
可以明显看出内容不是要修改的。

SFINAE在这种情况下有点棘手,因为成员本身不是模板。@DavidRodríguez dribeas有多棘手,真的吗?您在返回类型上制作模板和SFINAE。抱歉,我们不使用boost。有没有非增压解决方案?Boost太复杂了,我无法阅读和理解,抱歉。@Dirt
enable\u如果对我来说微不足道。@jrok:您需要将函数更改为模板,因为没有参数,编译器无法推断类型。在C++11中,可以使用默认模板参数,但在C++03中,函数模板不能使用默认模板参数,因此用户必须为您提供模板参数。与使用SFINAESFINAE相比,预先编写一个简单的特征或从模板库继承要容易得多。在这种情况下,SFINAESFINAE有点棘手,因为成员本身不是模板。@DavidRodríguez dribeas有多棘手,真的吗?您在返回类型上制作模板和SFINAE。抱歉,我们不使用boost。有没有非增压解决方案?Boost太复杂了,我无法阅读和理解,抱歉。@Dirt
enable\u如果对我来说微不足道。@jrok:您需要将函数更改为模板,因为没有参数,编译器无法推断类型。在C++11中,可以使用默认模板参数,但在C++03中,函数模板不能使用默认模板参数,因此用户必须为您提供模板参数。预先编写一个简单的特征或从模板库继承要比使用sfinae容易得多专门化会有多糟糕?我认为比专门化更重要的是重新设计类层次结构,抽象成员容器以获得统一的接口等。大约有十几个类,所有类都具有不同的模板容器,例如vector,列表等。我试图控制它们的声明和一些相关函数,并采取简单的方法。专门化会有多糟糕?我认为不仅仅是专门化所涉及的是重新设计类层次结构,抽象成员容器以获得统一的接口等。大约有十几个类都有不同的模板容器,例如vector、list等。我试图控制它们的声明和很少的相关函数,并采取简单的方法。