如何基于模板参数制作方法const

How to make a method const based on the template parameter?

本文关键字:制作方法 const 参数 何基于      更新时间:2023-10-16

我有一个带有模板参数的类,我想调用它的方法。看起来像这样:

template <typename T>
class Foo {
public:
    void doSomething() {
        for (auto& t: ts) {
            t.doSomething();
        }
    }
private:
    std::vector<T> ts;
};

这有效,但是如果T本身为const,我想制作doSomething() const(假定T::doSomething()也将是const)。我找到了一个可能的解决方案(基于这个问题),但我不喜欢它。

template <bool enabled = std::is_const<T>::value>
typename std::enable_if<enabled, void>::type
doSomething() const {
    for (auto& t: ts) {
        t.doSomething();
    }
}
template <bool enabled = !std::is_const<T>::value>
typename std::enable_if<enabled, void>::type
doSomething() {
    for (auto& t: ts) {
        t.doSomething();
    }
}

它可以正常工作,但是它具有代码重复。有什么方法可以避免它吗?

虽然在这里不完美是解决方法:我们有一个非const成员_doSomething(),其中我们的代码对const和non const的代码相同,除了在基础对象上调用的函数。由于该成员是non const,我们必须从const foo中调用 const_cast this

由于_doSomething内部的代码是安全的,因此(const_) const ake是安全的。

您的代码也不会为const编译,因为您无法拥有const的CC_11。向量的元素必须是可分配的, const types通常不是 不是(但是,它们确实不应该:https://stackoverflow.com/a/17313104/258418)。
您可能需要考虑std::vector<T*>而不是std::vector<T>。(即存储指针而不是向量中的对象)

#include <iostream>
#include <vector>
using namespace std;
class Bar {
public:
    Bar() {}
    void doSomething() const {
        std::cout << "const" << endl;
    }
    void doSomething() {
        std::cout << "NON const" << endl;
    }
};

template <typename T>
class Foo {
    void _doSomething() {
        /*for (auto& t: ts) {
            t.doSomething();
        }*/
        test.doSomething();
    }
public:
    Foo()/*T element) : ts({element})*/ {}
    template <bool enabled = std::is_const<T>::value>
    typename std::enable_if<enabled, void>::type
    doSomething() const {
        const_cast<typename std::remove_const<Foo<T>>::type*>(this)->_doSomething();
    }
    template <bool enabled = !std::is_const<T>::value>
    typename std::enable_if<enabled, void>::type
    doSomething() {
        _doSomething();
    }
private:
    //std::vector<T> ts; https://stackoverflow.com/a/17313104/258418
    T test;
};
int main()
{
    Foo<Bar> nonConstInst;
    Foo<const Bar> ConstInst;
    nonConstInst.doSomething();
    ConstInst.doSomething();
    return 0;
}