C ++模板构造函数的特化

时间:2009-12-14 19:02:36

标签: c++ templates constructor specialization

我有一个模板化的类A< T,int>和两个typedef A< string,20>和A< string,30>。 如何覆盖A< string,20>的构造函数? ?以下不起作用:

template <typename T, int M> class A;
typedef  A<std::string, 20> one_type;
typedef  A<std::string, 30> second_type;


template <typename T, int M>
class A {
public:
  A(int m) {test= (m>M);}

  bool test;

};


template<>
one_type::one_type() { cerr << "One type" << endl;}

我想要A&lt; std :: string,20&gt;类;做一些其他课没有做的事。如何在不更改构造函数A:A(int)?

的情况下执行此操作

7 个答案:

答案 0 :(得分:8)

唯一不能做的是使用typedef来定义构造函数。除此之外,您应该像这样专门化A<string,20>构造函数:

template<> A<string,20>::A(int){}

如果您希望A<string,20>拥有与通用A不同的 构造函数,则需要专门化整个A<string,20>类:

template<> class A<string,20> {
public:
   A( const string& takethistwentytimes ) { cerr << "One Type" << std::endl; }
};

答案 1 :(得分:6)

假设您的确实意味着A::test可以公开访问,您可以执行以下操作:

#include <iostream>


template <int M>
struct ABase
{
  ABase(int n) : test_( n > M )
  {}

  bool const test_;
};


template <typename T, int M>
struct A : ABase<M>
{
  A(int n) : ABase<M>(n)
  {}
};


template <typename T>
A<T, 20>::A(int n)
  : ABase<20>(n)
  { std::cerr << "One type" << std::endl; }

踢轮胎:

int main(int argc, char* argv[])
{
  A<int, 20> a(19);
  std::cout << "a:" << a.test_ << std::endl;
  A<int, 30> b(31);
  std::cout << "b:" << b.test_ << std::endl;
  return 0;
}

答案 2 :(得分:1)

你无法使用当前的方法。 one_type是特定模板特化的别名,因此它获取模板具有的任何代码。

如果要添加特定于one_type的代码,则必须将其声明为A specialization的子类,如下所示:

  class one_type:
    public A<std::string>, 20>
  {
    one_type(int m)
      : A<str::string, 20>(m)
    {
      cerr << "One type" << endl;
    }
  };

答案 3 :(得分:1)

怎么样:

template<typename T, int M, bool dummy = (M > 20) >
class A {
public:
  A(int m){
      // this is true
  }

};

template<typename T, int M>
class A<T,M,false> {
public:
    A(int m) {
    //something else
    }
};

答案 4 :(得分:1)

这可能有点迟了,但如果您有 template <class = typename std::enable_if< std::is_same<A<T,M>, A<std::string, 20>>::value>::type // Can be called only on A<std::string, 20> > A() { // Default constructor } 的访问权限,则可以使用SFINAE来完成您想要的内容:

const resultRenderer = ({ title, id }) => {
  console.log(id);
  return <div key={id}>{title}</div>;
};

class SearchBox extends React.Component {
  componentWillMount() {
    this.timer = null;
  }

  handleSearchChange = (e, { value }) => {
    clearTimeout(this.timer);

    const { updateSearchValue } = this.props;

    this.timer = setTimeout(() => {
      updateSearchValue(value);
      this.calculateSuggestions(value);
    }, 500);
  };

  calculateSuggestions = value => {
    const { resetSearch, fetchingSuggestions, getResults } = this.props;
    const { fetched } = this.props.search;
    if (value.length === 0) {
      resetSearch();
    } else if (value.length === 1 && !fetched) {
      getResults();
    } else if (value.length === 1 && fetched) {
      fetchingSuggestions();
    } else {
      fetchingSuggestions();
    }
  };

  handleResultSelect = (e, { result }) => {};

  render() {
    const { isLoading, suggestions, value } = this.props.search;
    return (
      <Grid>
        <Grid.Column width={8}>
          <Search
            loading={isLoading}
            onSearchChange={this.handleSearchChange}
            results={suggestions}
            value={value}
            resultRenderer={resultRenderer}
          />
        </Grid.Column>
      </Grid>
    );
  }
}

Working example

答案 5 :(得分:1)

最新但非常优雅的解决方案: C ++ 2020引入了Constraints and Concepts。现在,您可以有条件地启用和禁用构造函数和析构函数!

#include <iostream>
#include <type_traits>

template<class T>
struct constructor_specialized
{
    constructor_specialized() requires(std::is_same_v<T, int>)
    {
        std::cout << "Specialized Constructor\n";
    };

    constructor_specialized()
    {
        std::cout << "Generic Constructor\n";
    };
};

int main()
{
    constructor_specialized<int> int_constructor;
    constructor_specialized<float> float_constructor;
};

运行代码here

答案 6 :(得分:0)

我能够针对这种情况提出的最佳解决方案是使用&#34;构造函数辅助函数&#34;:

template <typename T, int M> class A;
typedef  A<std::string, 20> one_type;
typedef  A<std::string, 30> second_type;

template <typename T, int M>
class A {
private:
  void cons_helper(int m) {test= (m>M);}
public:
  A(int m) { cons_helper(m); }

  bool test;
};

template <>
void one_type::cons_helper(int) { cerr << "One type" << endl;}