0

有没有办法使用模板在你的主目录中创建一个标准的类构造函数?

如果我有一堂课:

我的班级.h

class myClass
{
private:
    float a;
public:
    myClass(float _a) {a = _a;}
    float getA(){return a;}
    ~myClass() {}
};

有没有办法在你的主要模板中像这样:

主文件

#include "myclass.h"

typedef myClass<5.0> Dummy

int main(int argc, char const *argv[])
{
    // EDIT: removed the following typo
    // Dummy dummy();
    Dummy dummy;
    std::cout << dummy.getA() << std::endl;
    return 0;
}

哪个应该输出:

> 5.0000000

这样人们就可以主要定义一种标准的方式来构造实例。

4

4 回答 4

2

C++17 及以下

不幸的是,C++ 还不允许您将浮点类型用作非类型模板参数。也就是说,您可以通过将分子和分母接受为整数然后在类中执行“数学”以获得浮点值来伪造它。那看起来像

template<size_t numerator, size_t denominator = 1> // use a default value so you don't have to specify the denominator for whole values
class myClass
{
private:
    float a;
public:
    myClass(float _a = static_cast<float>(numerator) / denominator) : a(_a) {}
    float getA(){return a;}
    ~myClass() {}
};

typedef myClass<5> Dummy;

int main(int argc, char const *argv[])
{
    Dummy dummy; // notice this isn't Dummy dummy();.  That makes a function, not a variable
    std::cout << dummy.getA() << std::endl;
    return 0;
}

如果你愿意,你也可以添加一个默认值,numerator这样你就可以做到

// Pre C++17
myClass<> foo; 

//C++17 and later
myClass foo;

C++20

现在我们可以使用浮点类型1,代码可以简化为:

template<float default_value = 0.0f>
class myClass
{
private:
    float a;
public:
    myClass(float _a = default_value) : a(_a) {}
    float getA(){return a;}
    ~myClass() {}
};

typedef myClass<5.0f> Dummy;

int main(int argc, char const *argv[])
{
    Dummy dummy;
    std::cout << dummy.getA() << std::endl;
    return 0;
}

1:实际上还没有编译器支持这一点,但根据标准是允许的

于 2020-03-04T16:12:33.373 回答
1

建立在@pptaszni's answer的基础上,您可以创建一个“工厂工厂功能”:

auto makeMyClassFactory(float value) {
    return [=] {
        return myClass{value};
    };
}

auto const Dummy = makeMyClassFactory(5.0f);

int main(int argc, char const *argv[])
{
    auto dummy = Dummy();
    std::cout << dummy.getA() << std::endl;
    return 0;
}

在 Wandbox 上现场观看

于 2020-03-04T16:29:20.330 回答
0

不是真的,但你可以像这样编写一个工厂函数(或者更复杂的类):

myClass createMyClassV5()
{
  return myClass(5.0);
}

不幸的是,您不能将其float设为模板,因为不允许作为模板非类型参数。你可以这样做int

于 2020-03-04T16:14:30.623 回答
0

您最好只使用一个默认实例,只要您需要一个新实例,您就可以复制该实例:

#include "myclass.h"

Dummy myClass(5.0);

int main(int argc, char const *argv[])
{
    myClass dummy1 = Dummy;
    std::cout << dummy1.getA() << std::endl;
    myClass dummy2 = Dummy;
    std::cout << dummy2.getA() << std::endl;
    return 0;
}
于 2020-03-04T16:16:29.320 回答