【问题标题】:C++ template function resolutionC++模板函数解析
【发布时间】:2016-11-08 23:22:54
【问题描述】:

我有以下示例代码,想获得一些帮助以了解为什么我无法在 Linux 上使用 clang 和 g++ 编译它?

#include <iostream>

using namespace std;

typedef enum COLORS {
    RED = 0,
    GREEN,
    BLUE,
    ORANGE,
    MAROON,
    WHITE,
    BLACK
} COLORS;

template <COLORS C> void whatColor( COLORS x ) {
    cout << "this can be any color!!!" << endl;
}

template<> void whatColor<RED>( COLORS x ) {
    cout << "this is RED!!!" << endl;
}

template<> void whatColor<GREEN>( COLORS x ) {
    cout << "this is GREEN!!!" << endl;
}

template<> void whatColor<BLUE>( COLORS x ) {
    cout << "this is BLUE!!!" << endl;
}

template<> void whatColor<ORANGE>( COLORS x ) {
    cout << "this is ORANGE!!!" << endl; 
}

int main( ) {
    const COLORS red=RED;

    whatColor( red );
    whatColor<RED>( RED );
    whatColor<red>( red );
    whatColor<RED>( red );
}

我看到的失败是这样的:

CXX [misc]  tmpl.cpp
src/tmpl.cpp:40:2: error: no matching function for call to 'whatColor'
    whatColor( red );
    ^~~~~~~~~
src/tmpl.cpp:15:26: note: candidate template ignored: couldn't infer template argument 'C'
template <COLORS C> void whatColor( COLORS x ) {
                     ^
1 error generated.
make: *** [obj/tmpl.o] Error 1

我不清楚为什么在这种情况下它不能推断出参数类型

【问题讨论】:

    标签: templates g++ clang template-specialization clang++


    【解决方案1】:

    用代码:

    template <COLORS C> void whatColor( COLORS x ){...}
    

    你定义了一个模板函数,以 Color 类型的值 C 为模板,这个函数也巧合地将 Color x 作为参数(实际上并没有使用)

    然后,您还可以针对 C 的一些可能值专门化该函数。

    当你打电话时

    whatColor( red );
    

    您提供的是颜色 x 的值,而不是 C 的值。由于 X 和 C 不相关(即使它们恰好都是颜色),因此编译器无法决定使用 C 的哪个值.

    您应该在代码尝试混合使用这两种颜色时决定是动态输入颜色还是静态输入颜色(是否在编译时固定)

    例如,目前可以这样称呼它

    whatColor<RED>( BLUE );
    

    这真的有点奇怪。 C = RED,X = BLUE(但 X 被忽略)

    如果你想在编译时修复颜色,你可以删除 X 函数参数,只使用 C 模板参数

    template <COLORS C> void whatColor() //definition
    whatColor<RED>(); // call
    

    或者如果你希望函数使用 X 参数,那么不要使用模板

    void whatColor(COLORS X)
    {
        // maybe use a switch statement on X
    }
    

    如果不同的颜色是不同的类型而不是值,那么重载或模板代码将起作用(我不建议这样做)

    class Red{};
    class Blue{};
    template <typename COLORSTYPE> void whatColor( COLORSTYPE x )
    { 
       // ...
    }
    

    // 或重载

    void whatColor(Red dummy){//...}
    void whatColor(Blue dummy){//...}
    
    Red red;
    whatColor(red);
    

    【讨论】:

    • 嗨@ROX,我已经删除了函数的输入参数,如果模板参数是 COLORS 常量,它可以正常工作。但是,我还需要它能够采用 COLORS 变量:COLORS red=RED; whatColor&lt;red&gt;( ); 如果我将 red 设为 const,编译器似乎足够聪明,可以推断出类型并且它可以工作。但是,如果它不是 const 它甚至不会编译。给出这个错误:src/tmpl.cpp:41:2: error: no matching function for call to 'whatColor' whatColor( ); src/tmpl.cpp:15:26: 注意:候选模板被忽略:显式指定无效...
    • C++ 模板需要在编译时固定的类型或值。如果要使用运行时变量,则不能将其用作模板参数。 (如果您真的想使用模板来处理每种颜色,您可以在上面的 switch 语句示例中执行此操作)。我认为您现在的错误消息是因为它试图按类型匹配模板参数,该类型固定为颜色,而不是按未固定的值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多