当前位置: 首页 > 知识库问答 >
问题:

为什么用enable_if编译错误

张照
2023-03-14

为什么这不能用gcc48和clang32编译?

#include <type_traits>

template <int N> 
struct S {

    template<class T> 
    typename std::enable_if<N==1, int>::type
    f(T t) {return 1;};

    template<class T> 
    typename std::enable_if<N!=1, int>::type
    f(T t) {return 2;};
};

int main() {
    S<1> s1;
    return s1.f(99);
}

GCC错误:

/home/lvv/p/sto/test/t.cc:12:2: error: no type named ‘type’ in ‘struct enable_if<false, int>’
  f(T t) {return 2;};
  ^

叮当声错误:

/home/lvv/p/sto/test/t.cc:11:26: error: no type named 'type' in 'std::enable_if<false, int>'; 'enable_if' cannot be used to
      disable this declaration
        typename std::enable_if<N!=1, int>::type
                                ^~~~
/home/lvv/p/sto/test/t.cc:16:7: note: in instantiation of template class 'S<1>' requested here
        S<1> s1;
             ^

编辑-解决方案

我已经接受了查尔斯·萨尔维亚的回答,但出于实际原因,我无法使用提出的变通方法(专门研究N)。我找到了其他适合我的解决办法。如果依赖于T,则启用_:

typename std::enable_if<(sizeof(T),N==1), int>::type

共有3个答案

毋承基
2023-03-14

要让std::enable_if像这样工作,您需要依赖SFINAE。不幸的是,在你宣布

S<1> s1;

它将实例化所有的S

对于这样的事情,我可能会遵循单独的模板结构:

template <bool B>
struct f_functor {
    template <typename T>
    static int f(T t) { return 1; }
};

template <>
struct f_functor<false> {
    template <typename T>
    static int f(T t) { return 2; }
};

template <int N> 
struct S {

    template<class T> 
    typename int f(T t) { return f_functor<N==1>::f(t); }
};

璩无尘
2023-03-14

好吧,我不确定你想做什么,但也许这段代码会有所帮助:

#include <iostream>

template <int N>
struct S {

    template<class T=int>
    typename std::enable_if<N==1, T>::type
    f(T t) {return 1;}

    template<class T=int>
    typename std::enable_if<N!=1, T>::type
    f(T t) {return 2;}
};

int main()
{
    S<1> s1;
    S<2> s2;
    std::cout << s1.f(99) << " " << std::endl << s2.f(5);
}

这打印1和2。

诸葛乐逸
2023-03-14

因为您在函数模板中使用enable_if而不使用模板参数T。如果您想在结构S具有特定模板参数值N时进行特化,则需要使用类模板特化。

template <int N, class Enable = void> 
struct S {  };

template <int N>
struct S<N, typename std::enable_if<N == 1>::type>
{
  ....
};
 类似资料:
  • 问题内容: 遇到一个错误地使用 而不是 在其代码中的人,它没有显示为编译错误。 是因为 是相同的 ? 问题答案: 没有编译错误,因为它是有效的(尽管相当无用) 一元运算符 ,其使用方式与以下方式相同: Java语言规范中的相关部分是Unary Plus运算符+(第15.15.3节) 。它指定调用一元运算会导致操作数的一元数值提升(第5.6.1节)。这意味着: * 如果操作数是编译时类型的,,,或,

  • 问题内容: 为什么在下面的代码中没有出现编译错误?我得到一个有点混乱的地方。是因为它们有关系吗? 问题答案: 为什么在下面的代码中没有出现编译错误? 因为编译器只关心您要强制转换的表达式的静态类型。 看这两行: 您 知道在第二行中,由于第一行,该值仅引用类型的对象,而编译器则没有。对于所有的编译器知道(编译第二线时),它 可能 实际上已经: …哪里有扩展和实现的类。因此它是有效的(在编译时),以铸

  • 问题内容: 如果你给 它没有编译,但是带有花括号的相同代码是: 有什么解释? 问题答案: 基本上,变量声明只能在块中声明。 查看 Java语言规范中“语句”的语法 -它包括Block,但不包括LocalVariableDeclarationStatement- 后者是block语法的一部分。 这实际上是实用主义的问题:如果没有括号,则只能使用一个语句。如果没有后续语句,则声明变量是没有意义的,因为

  • 问题内容: 我正在尝试使用泛型实现以下结构。收到编译器错误,无法找出原因。 这个想法是译者使用T作为字典中键的类型。例如,可以是字符串或枚举。子类提供具体的字典。 但是它失败,因为:“类型’String’不符合协议’Hashable’” 但是String符合Hashable。它也不适用于Int,后者也符合Hashable。 如果删除类型约束,则仅用于测试(在此我还必须禁用字典,因为我不能在其中使用