【问题标题】:SFINAE check for template parameter operatorsSFINAE 检查模板参数运算符
【发布时间】:2020-01-23 08:22:50
【问题描述】:

能否告诉我为什么以下代码无法编译(在 MSVC 中“找不到匹配的重载函数”):

template<typename V>
struct LinearModel { // has basis vectors
    template<typename T = V>
    auto consolidation() const -> decltype(std::declval<T>() += (std::declval<T>() *= double())) {
        V linearCombination;
        // linearly combine basis vectors using += and *=
        return linearCombination;
    }
};

int main(){
    LinearModel<double> lm;
    auto c = lm.consolidation(); // the line that produces the error
    return 0;
}

我的意图是仅为具有T&amp; operator *=(double)T&amp; operator +=(T)T 定义LinearModel&lt;T&gt;::consolidation()

【问题讨论】:

  • 您的意思是写std::declval&lt;double&gt;()double() 而不仅仅是double?目前,您正在尝试将值和类型相乘。
  • @Kerndog73 啊,是的。 std::declval&lt;double&gt;()double() 有区别吗?
  • 可能不会。 std::declval 用于不一定是默认可构造的类型。 std::declval&lt;T&gt;() 总是比T() 好,但如果你知道它是double,那么你可以写double()
  • @Kerndog73 我解决了这个问题(如问题),但它仍然给出同样的错误!

标签: c++ templates c++14 sfinae decltype


【解决方案1】:

declval for T 返回T&amp;&amp;,不允许将*=(或其他赋值操作)的结果赋值给R-value。

如果你想获得左值使用:declval&lt;T&amp;&gt;():

    -> std::remove_reference_t<decltype(std::declval<T&>() += (std::declval<T&>() *= double{}))> 

Live demo

【讨论】:

  • 实际上返回类型可以简单地指定为V。我这样做只是因为我需要检查operator*=(double)operator+=(V) 的存在。知道了这一点,你会推荐更简单的吗?
【解决方案2】:

根据@rafix07 的回答,我最后做了什么:

    template<typename T = std::remove_reference_t<decltype(std::declval<V&>() += (std::declval<V&>() *= double()))>>
    T consolidation() const {
        T linearCombination;
        // ...
        return linearCombination;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    • 2016-09-21
    • 2021-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多