函数中的条件cv限定符

时间:2014-05-02 20:30:24

标签: c++ templates c++11

我想有条不紊地制作一个方法。也就是说,我们有

template <bool isConst>
class A {
    // stuff
};

取决于模板参数的值,

void method() const;

void method();

出现在A的正文中。

我的第一个想法是尝试条件类型,但这显然不起作用。

2 个答案:

答案 0 :(得分:3)

显而易见的解决方案是专业化:

template<bool>
struct A
{
    void method() const
    {
        std::cout << "const" << std::endl;
    }
};

template<>
struct A<false>
{
    void method()
    {
        std::cout << "non-const" << std::endl;
    }
};

如果您有更多方法并且不想复制它们,请将A作为基类A_base并从中派生A。 (我将其添加到下面的实例中)

Live example

答案 1 :(得分:2)

编辑:这只是出于利益的考虑。我不建议在商业产品中实际这样做。如果你正在尝试的话,也许在个人项目中。

你可以做的事情,这有点hacky,是这样的:

template< bool OnlyConst >
class TestClass
{
  struct Placeholder {};
public:

  template< class T >
  typename std::enable_if< OnlyConst && !std::is_same<T, Placeholder>::value, void >::type 
    MyFunc() const 
  { std::cout << "Const version"; }

  template< class T >
  typename std::enable_if< !OnlyConst && !std::is_same<T, Placeholder>::value, void >::type 
    MyFunc() 
  { std::cout << "Nonconst version"; }
};

不幸的是,函数确实需要模板化才能使用enable_if,如果你与该模板无关,那么调用者仍然需要提供它,以便编译器可以“使用”它。您也不能使用T的默认模板参数。

如果你能找到一个可以让编译器自动确定其类型的T的用途,那么它会很好用。

现在你在调用时必须总是为T赋值:

test.MyFunc<void>(); // even though the void doesn't affect it at all

占位符结构仅存在,因为SFINAE(至少在VS2012上)似乎希望T成为确定函数是否可以实例化的一部分。所以is_same调用几乎只是为了在enable_if中坚持使用一些。

我已经在VS2012中使用上面的代码进行了测试,似乎有效。