C++ 转换构造函数的隐式参数

C++ 转换构造函数的隐式参数,c++,implicit-conversion,implicit,default-arguments,dynamic-scope,C++,Implicit Conversion,Implicit,Default Arguments,Dynamic Scope,tl;Dr:有没有方法将当前范围中的默认参数添加到C++中的所有隐式构造函数? 我目前正在设计一个C++语言的嵌入式接口。目标是使语法正确的表达式的创建既安全又方便。现在,我认为学习像boost::proto这样的重量级实现会给开发带来太大的延迟,所以我尝试推出自己的实现 下面是一个小演示: #include <iostream> #include <string> #include <sstream> class ExprBuilder { public:

tl;Dr:<强>有没有方法将当前范围中的默认参数添加到C++中的所有隐式构造函数?

我目前正在设计一个C++语言的嵌入式接口。目标是使语法正确的表达式的创建既安全又方便。现在,我认为学习像boost::proto这样的重量级实现会给开发带来太大的延迟,所以我尝试推出自己的实现

下面是一个小演示:

#include <iostream>
#include <string>
#include <sstream>

class ExprBuilder
{
public:
    ExprBuilder(const int val) : val(std::to_string(val)) {}
    ExprBuilder(const std::string val) : val(val) {}
    ExprBuilder(const char* val) : val(val) {}

    ExprBuilder(const ExprBuilder& lhs, const ExprBuilder& arg) {
        std::stringstream ss;
        ss << "(" << lhs.val << " " << arg.val << ")";
        val = ss.str();
    }

    const ExprBuilder operator()(const ExprBuilder& l) const {
        return ExprBuilder(*this, l);
    }

    template<typename... Args>
    const ExprBuilder operator()(const ExprBuilder& arg, Args... args) const
        {
            return (*this)(arg)(args...) ;
        }

    std::string val;
};

std::ostream& operator<<(std::ostream& os, const ExprBuilder& e)
{
    os << e.val;
    return os;
}

int main() {
    ExprBuilder f("f");
    std::cout << f(23, "foo", "baz") << std::endl;
}
#包括
#包括
#包括
类ExprBuilder
{
公众:
ExprBuilder(const int val):val(std::to_string(val)){}
ExprBuilder(const std::string val):val(val){}
ExprBuilder(const char*val):val(val){}
ExprBuilder(const ExprBuilder&lhs、const ExprBuilder&arg){
std::stringstream-ss;

ss如果没有全局/静态变量,这几乎是不可能的,因为如果没有全局/静态信息,局部变量
Owner-Owner
ExprBuilder f
就无法相互了解

我认为最干净的方法是添加一个

static Owner* current_owner;
ExprBuilder
类。然后您可以添加一个新类
ScopedCurrentOwnerLock
,该类在构造函数中设置当前所有者
,并在析构函数中将其设置为nullptr。然后您可以使用它,类似于互斥锁:

class ScopedCurrentOwnerLock {
public:
    ScopedCurrentOwnerLock(Owner const& owner) {
        ExprBuilder::current_owner = &owner;
    }
    ~ScopedCurrentOwnerLock() {
        ExprBuilder::current_owner = nullptr;
    }
};

int main() {
    Owner owner;
    ScopedCurrentOwnerLock lock(owner);
    ExprBuilder f("f");
}
如果您有权访问
所有者
代码,则可以省略
ScopedCurrentOwnerLock
类,直接在
所有者
的构造函数/析构函数中设置/取消设置指针

请注意此解决方案存在以下两个问题:

  • 如果所有者在锁超出范围之前超出范围,则指针无效

  • 如果同时有多个锁,静态指针的行为是不可预测的,例如由于多线程


您所有的
exprbuilder
都依赖于
所有者
,您当然不需要全局状态。因此您必须将所有者传递给每个构造函数

如果您确实不想将
所有者添加到块中的所有实例化中,
,您可以创建一个工厂来为您传递它

struct ExprBuilderFactory
{
    Owner & owner;
    ExprBuilder operator()(int val) { return ExprBuilder(owner, val); }
    ExprBuilder operator()(char * val) { return ExprBuilder(owner, val); }
    // etc
}

int main() {
    Owner owner;
    ExprBuilderFactory factory{ owner };
    ExprBuilder f = factory("f");
}

我认为您所说的是某种
全局变量
您可以使用
Owner
Raii设置一个静态/全局变量,并在
ExprBuilder
中使用该全局变量。您的意思是使用唯一的\u ptr作为全局变量,以确保它仅在上下文中使用,并且必须显式保留吗如果用户忘记了指针,则不会产生运行时错误?@appleapple OP已经说过“我不想在这里使用静态字段”。静态成员变量是全局变量的一种特殊类型。我强烈怀疑他的反对意见会适用于任何其他类型。@choeger:我想你有一个全局变量(如果这是遗留代码,则可能是指向某个对象的指针),然后是一个RAII类,用于设置该全局变量并随后取消设置。
struct ExprBuilderFactory
{
    Owner & owner;
    ExprBuilder operator()(int val) { return ExprBuilder(owner, val); }
    ExprBuilder operator()(char * val) { return ExprBuilder(owner, val); }
    // etc
}

int main() {
    Owner owner;
    ExprBuilderFactory factory{ owner };
    ExprBuilder f = factory("f");
}