c++ - 程序在 Visual Studio 2012 中运行,但不在 ideone.com 中运行

标签 c++ visual-studio-2012 c++11 language-lawyer

我有一种直觉,VS2012 在这方面是错误的,但我不确定。

看了之后this question ,我想尝试实现类似的东西。

我的版本在 Visual Studio 2012 上运行良好,但甚至无法在 Ideone 上编译.

这是我的主界面:

#include <iostream>
#include <string>

template <class In, class Out>
struct Pipe
{
    typedef In in_type ;
    typedef Out out_type ;

    In in_val ;

    Pipe (const in_type &in_val = in_type()) : in_val (in_val)
    {
    }

    virtual auto operator () () const -> out_type
    {
        return out_type () ;
    }
};

template <class In, class Out, class Out2>
auto operator>> (const Pipe <In, Out> &lhs, Pipe <Out, Out2> &rhs) -> Pipe <Out, Out2>&
{
    rhs = lhs () ;
    return rhs ;
}

template <class In, class Out>
auto operator>> (const Pipe <In, Out> &lhs, Out &rhs) -> Out&
{
    rhs = lhs () ;
    return rhs ;
}

下面是几个测试类:

struct StringToInt : public Pipe <std::string, int>
{
    StringToInt (const std::string &s = "") : Pipe <in_type, out_type> (s)
    {
    }

    auto operator () () const -> out_type
    {
        return std::stoi (in_val) ;
    }
};

struct IntSquare : public Pipe <int, int>
{
    IntSquare (int n = 0) : Pipe <in_type, out_type> (n)
    {
    }

    auto operator () () const -> out_type
    {
        return in_val * in_val ;
    }
};

struct DivideBy42F : public Pipe <int, float>
{
    DivideBy42F (int n = 0) : Pipe <in_type, out_type> (n)
    {
    }

    auto operator () () const -> out_type
    {
        return static_cast <float> (in_val) / 42.0f ;
    }
};

这是驱动程序:

int main ()
{
    float out = 0 ;
    StringToInt ("42") >> IntSquare () >> DivideBy42F () >> out ;
    std::cout << out << "\n" ;

    return 0 ;
}

Ideone 提示模板推导,它无法找到正确的 operator>> 候选函数:

prog.cpp: In function ‘int main()’:
prog.cpp:75:21: error: no match for ‘operator>>’ (operand types are ‘StringToInt’ and ‘IntSquare’)
  StringToInt ("42") >> IntSquare () >> DivideBy42F () >> out ;
                     ^
prog.cpp:75:21: note: candidates are:
prog.cpp:23:6: note: Pipe<Out, Out2>& operator>>(const Pipe<In, Out>&, Pipe<Out, Out2>&) [with In = std::basic_string<char>; Out = int; Out2 = int]
 auto operator>> (const Pipe <In, Out> &lhs, Pipe <Out, Out2> &rhs) -> Pipe <Out, Out2>&
      ^
prog.cpp:23:6: note:   no known conversion for argument 2 from ‘IntSquare’ to ‘Pipe<int, int>&’
prog.cpp:30:6: note: template<class In, class Out> Out& operator>>(const Pipe<In, Out>&, Out&)
 auto operator>> (const Pipe <In, Out> &lhs, Out &rhs) -> Out&
      ^
prog.cpp:30:6: note:   template argument deduction/substitution failed:
prog.cpp:75:35: note:   deduced conflicting types for parameter ‘Out’ (‘int’ and ‘IntSquare’)
  StringToInt ("42") >> IntSquare () >> DivideBy42F () >> out ;

哪个编译器是正确的?如果 Ideone 是正确的,是否可以轻松修复此代码?

最佳答案

Ideone(实际上是 GCC)在这里是正确的。在 Visual Studio 中,它由于臭名昭著的扩展而编译,该扩展允许临时对象绑定(bind)到非常量左值引用(标准禁止这样做)。

我看到了几种在标准 C++ 中解决这个问题的可能方法:

第一,不要在流水线阶段使用临时对象:

int main ()
{
    float out = 0 ;
    StringToInt stage1("42");
    IntSquare stage2;
    DivideBy24F stage3;
    stage1 >> stage2 >> stage3 >> out ;
    std::cout << out << "\n" ;

    return 0 ;
}

第二,创建一个“停留”函数(与 std::move 相反),并使用它:

template <class T>
T& stay(T &&x) { return x; }

int main ()
{
    float out = 0 ;
    stay(StringToInt ("42")) >> stay(IntSquare ()) >> stay(DivideBy42F ()) >> out ;
    std::cout << out << "\n" ;

    return 0 ;
}

三、提供运算符>>的重载,取右值引用:

template <class In, class Out, class Out2>
auto operator>> (const Pipe <In, Out> &&lhs, Pipe <Out, Out2> &&rhs) -> Pipe <Out, Out2>&
{
    return lhs >> rhs;  // Notice that lhs and rhs are lvalues!
}

当然,理想情况下,您还可以提供混合的 &、&&&&、& 重载。

关于c++ - 程序在 Visual Studio 2012 中运行,但不在 ideone.com 中运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26244661/

相关文章:

c# - 通过 clickonce 发布时如何更改 Setup.exe 图标

c# - 找不到 CreateQuery() 方法

c++ - 在元组的每个元素上一般调用成员函数

c++ - 当 Visual C++ 拒绝此基于模板 -"dependent"的枚举时,它是否正确?

c++ - inline 或 constexpr 函数的多个定义的含义

c++ - 服务阻止 Windows 启动

c++ - 截止时间计时器到期,现在怎么办?

XAML PathTooLongException

c++ - INSERT into database fetch id 执行后如何获取插入行的ID?

c++ - 使用脉冲编码调制将数据从一台电脑传输到另一台电脑