如何禁用实例化一个临时类?

时间:2018-08-07 02:04:46

标签: c++14 c++17 auto copy-elision deleted-functions

我正在使用一个表达式模板类,该模板类不应实例化以避免悬挂引用。但是我很想用auto声明一个变量,然后'auto'创建一个临时类的命名实例。

如何在以下代码中禁用临时类的自动声明?

class Base
{
};

class Temp : public Base
{
public:
    Temp()         {}
    Temp(int, int) {}
    Temp(const Temp&) = default;
    Temp(Temp&&)      = default;
};

Temp testFunc(int a, int b) {
    return Temp{a,b};
}

int main() {
    Base a = testFunc(1,2); // this should work
    auto b = testFunc(1,2); // this should fail to compile
    return 0;
}

2 个答案:

答案 0 :(得分:1)

您似乎想阻止用户在特定类型上使用auto。在任何版本的C ++中都是不可能的。如果用户写T t = <expr>;是合法的C ++,其中T<expr>的类型,则用户写auto t = <expr>;是合法的(忽略类数据成员)。就像您不能禁止某人使用模板参数推导将<expr>传递给模板函数一样。

您为防止使用auto所做的任何事情也会禁止其他类型的使用。

答案 1 :(得分:0)

一种选择是将Temp的构造函数设为私有,将testFunc移到Temp类中并使其静态。这样,您仍然可以实例化Base,但是auto会失败,因为您将调用私有构造函数:

class Base
{
};

class Temp : public Base
{
    Temp()         {}
    Temp(int, int) {}
    Temp(const Temp&) = default;
    Temp(Temp&&)      = default;

public:

    static Temp testFunc(int a, int b)
    {
        return Temp{a,b};
    }
};

int main() {
    Base a = Temp::testFunc(1,2); // this should work
    auto b = Temp::testFunc(1,2); // this should fail to compile
    return 0;
}

Demo