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++ 我能';t似乎无法使用enable\u来实例化类专门化_C++_Templates_C++11_Sfinae_Enable If - Fatal编程技术网

C++ 我能';t似乎无法使用enable\u来实例化类专门化

C++ 我能';t似乎无法使用enable\u来实例化类专门化,c++,templates,c++11,sfinae,enable-if,C++,Templates,C++11,Sfinae,Enable If,我试图创建一个类,该类具有模板方法实现的3个可能版本,这取决于模板类型是三个“类型集”之一。此外,我还试图在地图中保留这些对象的实例 所以我最初的尝试是: class DescriptorType { public: int id; DescriptorType() : id(-1) {} virtual ~DescriptorType() {} }; template <typename T> class Descriptor : public Descr

我试图创建一个类,该类具有模板方法实现的3个可能版本,这取决于模板类型是三个“类型集”之一。此外,我还试图在地图中保留这些对象的实例

所以我最初的尝试是:

class DescriptorType {
public:
    int id;
    DescriptorType() : id(-1) {}
    virtual ~DescriptorType() {}
};

template <typename T>
class Descriptor : public DescriptorType {
public:
    T value;

    void update(TYPE_CONSTRAINT((TYPE(int) || TYPE(float)))) {
        // specific implementation for these types
    }

    void update(TYPE_CONSTRAINT((TYPE(vec2) || TYPE(vec3) || TYPE(vec4)))) {
        // specific implementation for these types
    }

    void update(TYPE_CONSTRAINT((TYPE(mat2) || TYPE(mat3) || TYPE(mat4)))) {
        // specific implementation for these types
    }
};
但是会出现同样的链接器错误。

声明没有参数的函数的语法
foo(void)
严格来说是为了与C兼容。当
void
来自模板替换时,它不起作用。(实际上,您并没有得到
void
,但根据评论,这是您的意图。)

SFINAE仅适用于即时声明中的模板参数。不能使用类模板的参数禁用成员函数。(这条规则非常烦人,但即使是大规模概念提案也没有建议改变它。)

要禁用基于类模板参数的成员,需要添加一个伪模板参数,然后使SFINAE看起来依赖于它。SFINAE也可以安全地放置在模板参数默认参数中:

#define TYPE_CONSTRAINT(x) enable_if_t< (bogus(), x) >


template< typename bogus = void,
    typename = TYPE_CONSTRAINT((TYPE(int) || TYPE(float))) >
void update() {
#定义类型_约束(x)如果_t<(假(),x)>
模板
无效更新(){
仍然存在过载的问题。SFINAE在过载解决时发生,但会在声明过载时检查它们的相互兼容性。仅SFINAE不足以授予不同函数的兼容性,因此您也需要破坏该安全机制

#define TYPE_CONSTRAINT(x) enable_if_t< x, bogus >

template< typename bogus = void,
    void * = (TYPE_CONSTRAINT((TYPE(int) || TYPE(float))) *) nullptr >
void update() …


template< typename bogus = int, // Use different types here
    int * = (TYPE_CONSTRAINT((TYPE(vec2) || TYPE(vec3))) *) nullptr >
void update() …


template< typename bogus = char,
    char * = (TYPE_CONSTRAINT((TYPE(mat2) || TYPE(mat3))) *) nullptr >
void update() …
#定义类型约束(x)如果
模板
无效更新()…
template
无效更新()…
模板
无效更新()…


说真的,这是一个解决办法。好的一面是,你已经访问了SFINAE最黑暗的角落,并且活着讲述了这个故事!

我不明白你为什么会看到链接器错误,但是你的想法不会起作用,因为
如果
通过工作,那么启用。\u。在你的用例中,不会有任何替换失败,因为E没有模板参数替换发生。@ PraceToReI我用一种替代方法更新了我的问题,我假设我将取代整个类。但是我得到相同的结果。请避免与模板模板编程混合的不必要宏。这两个都是C++的复杂子系统,并且混合了两个可以并且将导致垃圾的级联。另外,您有一些宏假定未传递给它的令牌具有某些特定的含义,因为额外的威慑,这至少在上述一种情况下会导致错误发生。“我在玩电锯,为了让它更容易,我放火烧了它们,并在它们身上加了炸药,以改善它们的平衡,我不断受伤"在你工作的时候,考虑宏,然后丢弃它们:不要从它们开始。你的部分专业化思想的工作版本。DYP的优秀答案解释了它是如何工作的。我不确定我是否遵循。我应该能够在这个方法的所有3个版本中使用你的表单在单类在线定义中吗?或者我应该做3个分离吗?类专门化每个都有自己版本的“update”?同样,update方法应该不带任何参数,但是你放在那里的T我猜是类1,而不是方法模板类型,在这种情况下,我现在会被一个额外的未使用参数卡住(我想我可以将其设为默认值)。@SaldaVonSchwartz(如果有效)将
T
作为参数类型,而不是
void
。我花了一分钟才意识到这一点,所以我的初始答案解释了为什么不能将
void
放在那里。我会将其还原为答案。是的,重载还有一个单独的问题。我也会澄清。嗯,我想知道是否存在一个涵盖所有问题的现有问题基本上我的问题是,我从一个C++的小3D引擎中移植了一些Objto-C代码。这个代码与GL C-API之间的封装设置着色器值有关。在Obj-C中没有泛型,但是我可以选择一种方法,它是“ID”类型,它是无效的,并且仍然可以安全地测试它的成员资格。在这里,根据类型的不同,我需要调用某个gl函数,并根据glm的value_ptr函数将类中的T值强制转换为原始指针。该函数不允许我使用泛型T变量。我试图避免重载每个类型的方法,因为您不必为每个类型使用不同的类型d、 /cc@SaldaVonSchwartz
#define TYPE_CONSTRAINT(x) enable_if_t< (bogus(), x) >


template< typename bogus = void,
    typename = TYPE_CONSTRAINT((TYPE(int) || TYPE(float))) >
void update() {
#define TYPE_CONSTRAINT(x) enable_if_t< x, bogus >

template< typename bogus = void,
    void * = (TYPE_CONSTRAINT((TYPE(int) || TYPE(float))) *) nullptr >
void update() …


template< typename bogus = int, // Use different types here
    int * = (TYPE_CONSTRAINT((TYPE(vec2) || TYPE(vec3))) *) nullptr >
void update() …


template< typename bogus = char,
    char * = (TYPE_CONSTRAINT((TYPE(mat2) || TYPE(mat3))) *) nullptr >
void update() …