Boost tribool在C+中导致从右到左的条件求值+; 据我所知,C++在条件语句中总是从左到右进行计算。 if(A, B, C)

Boost tribool在C+中导致从右到左的条件求值+; 据我所知,C++在条件语句中总是从左到右进行计算。 if(A, B, C),c++,boost,c++11,conditional-statements,operator-precedence,C++,Boost,C++11,Conditional Statements,Operator Precedence,A将首先求值,B第二次求值,依此类推。但是,下面的示例显示了一些奇怪的行为 #include <iostream> #include <map> #include <memory> #include <vector> #include <boost/logic/tribool.hpp> //-//////////////////////////////////////////// // File Block class FileBl

A
将首先求值,
B
第二次求值,依此类推。但是,下面的示例显示了一些奇怪的行为

#include <iostream>
#include <map>
#include <memory>
#include <vector>

#include <boost/logic/tribool.hpp>

//-////////////////////////////////////////////
// File Block
class FileBlock {
public:
    FileBlock();
    virtual ~FileBlock();
    bool linked();

    std::vector<int> messages_;

private:
    boost::logic::tribool position_;
    std::shared_ptr<FileBlock> precedingBlock_ = nullptr;
    std::shared_ptr<FileBlock> followingBlock_ = nullptr;
};

FileBlock::FileBlock()  {
    std::cout << "Breakpoint." << std::endl;

    // "linked()" evaluated first by scope.
    if(linked())    {
        if(!position_
            && precedingBlock_->messages_.back() > 1)   {
                std::cout << "Unreachable." << std::endl;
        }
    }

    // "linked()" evaluated first without the tribool.
    if(linked()
        && precedingBlock_->messages_.back() > 1)   {
            std::cout << "Unreachable." << std::endl;
    }

    // "precedingBlock_->messages_.back() > 1" evaluated first. (Crash because null.)
    if(linked()
        && !position_
        && precedingBlock_->messages_.back() > 1)   {
            std::cout << "Unreachable." << std::endl;
    }
}

FileBlock::~FileBlock() {}

bool FileBlock::linked()    {
    return false;
}

//-////////////////////////////////////////////
// main
int main()  {
    std::shared_ptr<FileBlock> followingBlock(new FileBlock());

    return 0;
}
以下是我的构建命令:

g++ -std=gnu++11 -O0 -g3 -Wall -c -fmessage-length=0 -o "src\\main.o" "..\\src\\main.cpp" 
g++ -o wtf.exe "src\\main.o" 

与内置逻辑运算符不同,重载逻辑运算符(and)没有从左到右的求值顺序(也没有短路语义)。操作数的求值顺序几乎与其他任何地方一样未指定。

现在我们有了lambda,我们应该在
&&
上推出基于短路的重载选项。类似于
模板tribool操作符&&(tribool b,RHS&&RHS,int)
的东西,如果我们想走
++
路线,或者我们可以使用其他语法来表示“替代重载语义”,这不会吸引人(建议?)。然后
rhs
将是一个
lambda
,由
&
子句右侧的语言(使用
[&]
捕获)隐式创建。在
&&
重载中,我们可以选择对其求值(使用
()
)或不求值,从而允许短路式逻辑。重载逻辑运算符不按从左到右的求值顺序求值,而成员函数按从左到右的求值顺序求值,这有什么原因吗?@Präriewolf成员函数也不这样做@jrok所以不能保证第二个条件总是按照这个顺序检查?从左到右的顺序由1)内置逻辑运算符(
&&&
|
),2)条件运算符(先是
左边的操作数,然后是剩下的一个操作数),3)内置逗号运算符,4)括号内的初始值设定项列表(
{}
)。我认为这涵盖了一切。在其他任何地方,顺序都是不明确的。
g++ -std=gnu++11 -O0 -g3 -Wall -c -fmessage-length=0 -o "src\\main.o" "..\\src\\main.cpp" 
g++ -o wtf.exe "src\\main.o"