模板别名、变量模板和自动类型推导无法推导模板参数

Template Alias, Variable Template, and auto type deduction failing to deduce template argument

在处理我的 class 声明时,我对如何在尝试使用自动类型推导时在非 class 模板中使用别名模板和模板变量感到困惑。

Signal.h

#ifndef SIGNAL_H
#define SIGNAL_H

#include <cstdint>

template<typename T>
using TimeSignal = T;

using DiscreteTime = TimeSignal<std::uint8_t>;
using ContinuousTime = TimeSignal<double>;

class Signal {
private:
    template<typename T>
    static TimeSignal<T> time_;

    double voltage_;
    double current_;

public:
    template<typename T>
    explicit Signal( TimeSignal<T> time, double voltage = 0, double current = 0 ) :
        voltage_{voltage}, current_{current}
    { time_ = time; }

     double sampleVoltage() { return voltage_; }
     double sampleCurrent() { return current_; }

     template<typename T>
     static auto atTime() { return time_; }         
};

#endif // SIGNAL_H

我会这样使用它:

#include <iostream>
#include "Signal.h"

int main() {
    DiscreteTime t1{ 5 };
    ContinuousTime t2{ 7.5 };

    Signal s1{ t1, 3.5, 0.05 );
    Signal s2{ t2, 4.3, 0.09 );

    auto time1 = s1.atTime();
    auto time2 = s2.atTime();

    return 0;
}

我不想模板化这个 class,所以我在考虑有一个内部变量模板。在 class 之外,我试图使用模板别名来使不同的 "TimeSignals" 具有描述性,因为 "DiscreteTime" 通常是 integral typeContinousTime浮点数或实数集。然而,我正在模板化这个 class 的构造函数,它接受 TimeSignal 类型并希望 class 推断或自动将其内部变量模板解析为该类型,具体取决于两者中的哪一个类型被传入。最后我试图对 return 那个类型使用自动类型推导。

我不知道是语法问题还是用法问题,但这让我很困惑。我不确定如何让它进入工作编译状态。

这是 Visual Studio 2017 给我的当前编译器错误。

1>------ Build started: Project: Circuit Maker Simulator, Configuration: Debug x64 ------
1>main.cpp
1>c:\...\main.cpp(15): error C2672: 'Signal::atTime': no matching overloaded function found
1>c:\...\main.cpp(15): error C2783: 'auto Signal::atTime(void)': could not deduce template argument for 'T'
1>c:\...\Signal.h(64): note: see declaration of 'Signal::atTime'
1>c:\...\main.cpp(24): error C2672: 'Signal::atTime': no matching overloaded function found
1>c:\...\main.cpp(24): error C2783: 'auto Signal::atTime(void)': could not deduce template argument for 'T'
1>c:\...\Signal.h(64): note: see declaration of 'Signal::atTime'
1>Done building project "Circuit Maker Simulator.vcxproj" -- FAILED.

他们所说的编译器错误很明显,但就像他们在没有任何帮助、帮助或建议来解决或解决这个问题的情况下对我尖叫或大喊大叫...

编辑

用户 rafix07 的回答对我帮助很大,很有帮助。我遗漏了几件事,如果我一直盯着它看足够长的时间,我可能最终会发现其中两件事,那就是 class 中需要它的模板参数或参数的变量模板的使用。另一个是在主函数中使用范围解析运算符来调用静态函数。给我一些时间我可以找到它们。

让我陷入困境的一个问题是我必须在调用它时显式实例化我想要的类型的函数模板。这就是让我为我们的头发拔掉头发的人......

根据他的回答中的 link 调整代码后,我现在可以编译了,但是我现在收到 linker 未解析的外部符号错误,它与模板变量。这应该不是问题,只需要在cpp文件中定义它来解析静态变量。

首先,atTime 是静态方法,因此调用它的唯一方法是使用范围解析运算符 ::atTime 不接受任何参数,因此无法推导出 T,您需要明确地将类型放入模板参数列表中:

auto time1 = Signal::atTime<DiscreteTime>();
auto time2 = Signal::atTime<ContinuousTime>();

SignalatTime 函数的构造函数中,您必须指定 T 访问哪个变量模板:

template<typename T>
explicit Signal( TimeSignal<T> time, double voltage = 0, double current = 0 ) :
    voltage_{voltage}, current_{current}
{ time_<T> = time; }

Full working code is here.