如何根据模板参数制作方法const?

pet*_*ohn 10 c++ const

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

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

这是有效的,但我想制作doSomething()const如果T它本身是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();
    }
}
Run Code Online (Sandbox Code Playgroud)

它工作正常,但它有代码重复.有什么办法可以避免吗?

ted*_*ted 3

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

由于里面的代码_doSomething是 const 安全的,所以 (const_)cast 也是安全的const

您的代码也不会编译为 const,因为您不能拥有vectorof const。向量的元素必须是可分配的,而通常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; /sf/answers/1211917311/
    T test;
};

int main()
{
    Foo<Bar> nonConstInst;
    Foo<const Bar> ConstInst;

    nonConstInst.doSomething();
    ConstInst.doSomething();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)